Example #1
0
async def claim_invite(request):
    user = await check_authorized(request)
    data = await request.json()
    room = Room.get_or_none(invitation_code=data["code"])
    if room is None:
        return web.HTTPNotFound()
    else:
        if user != room.creator and not PlayerRoom.get_or_none(player=user,
                                                               room=room):
            query = PlayerRoom.select().where(PlayerRoom.room == room)
            try:
                loc = query.where(
                    PlayerRoom.role == Role.PLAYER)[0].active_location
            except IndexError:
                loc = query.where(
                    PlayerRoom.role == Role.DM)[0].active_location
            PlayerRoom.create(player=user,
                              room=room,
                              role=Role.PLAYER,
                              active_location=loc)

            for csid in game_state.get_sids(player=room.creator, room=room):
                await sio.emit(
                    "Room.Info.Players.Add",
                    {
                        "id": user.id,
                        "name": user.name
                    },
                    room=csid,
                    namespace="/planarally",
                )
        return web.json_response({
            "sessionUrl":
            f"/game/{urllib.parse.quote(room.creator.name, safe='')}/{urllib.parse.quote(room.name, safe='')}"
        })
Example #2
0
async def create(request):
    allow_new_sessions = config.getboolean("Access control",
                                           "allow_new_sessions")
    if not allow_new_sessions:
        return web.HTTPConflict(
            reason="This feature is disabled by administrator")

    user = await check_authorized(request)
    data = await request.json()
    roomname = data["name"]
    if not roomname:
        return web.HTTPBadRequest()
    else:
        with db.atomic():
            default_options = LocationOptions.create()
            room = Room.create(name=roomname,
                               creator=user,
                               default_options=default_options)
            loc = Location.create(room=room, name="start", index=1)
            loc.create_floor()
            PlayerRoom.create(player=user,
                              room=room,
                              role=Role.DM,
                              active_location=loc)
            room.save()
        return web.HTTPOk()
Example #3
0
async def claim_invite(request):
    user = await check_authorized(request)
    data = await request.json()
    room = Room.get_or_none(invitation_code=data["code"])
    if room is None:
        return web.HTTPNotFound()
    else:
        if user.name != room.creator and not PlayerRoom.get_or_none(
                player=user, room=room):
            PlayerRoom.create(player=user, room=room)

            for csid in state.get_sids(user=room.creator, room=room):
                await sio.emit(
                    "Room.Info.Players.Add",
                    {
                        "id": user.id,
                        "name": user.name
                    },
                    room=csid,
                    namespace="/planarally",
                )
        return web.json_response({
            "sessionUrl":
            f"/game/{urllib.parse.quote(room.creator.name, safe='')}/{urllib.parse.quote(room.name, safe='')}"
        })
Example #4
0
async def create(request: web.Request):
    user: User = await check_authorized(request)
    data = await request.json()
    roomname = data["name"]
    logo = data["logo"]
    if not roomname:
        return web.HTTPBadRequest()
    else:

        if Room.get_or_none(name=roomname, creator=user):
            return web.HTTPConflict()

        with db.atomic():
            default_options = LocationOptions.create()
            room = Room.create(
                name=roomname,
                creator=user,
                default_options=default_options,
            )

            if logo >= 0:
                room.logo_id = logo

            loc = Location.create(room=room, name="start", index=1)
            loc.create_floor()
            PlayerRoom.create(player=user, room=room, role=Role.DM, active_location=loc)
            room.save()
        return web.HTTPOk()
Example #5
0
async def claim_invite(request):
    user = await check_authorized(request)
    room = Room.get_or_none(invitation_code=request.match_info["code"])
    if room is None:
        return web.HTTPNotFound()
    else:
        if user.name != room.creator and not PlayerRoom.get_or_none(
                player=user, room=room):
            PlayerRoom.create(player=user, room=room)
        return web.HTTPFound(f"/rooms/{room.creator.name}/{room.name}")
Example #6
0
async def claim_invite(request):
    user = await check_authorized(request)
    data = await request.json()
    room = Room.get_or_none(invitation_code=data["code"])
    if room is None:
        return web.HTTPNotFound()
    else:
        if user.name != room.creator and not PlayerRoom.get_or_none(
                player=user, room=room):
            PlayerRoom.create(player=user, room=room)
        return web.json_response(
            {"sessionUrl": f"/game/{room.creator.name}/{room.name}"})
Example #7
0
async def connect(sid, environ):
    user = await authorized_userid(environ["aiohttp.request"])

    if user is None:
        await sio.emit("redirect", "/", room=sid, namespace=GAME_NS)
        return

    ref = {
        k.split("=")[0]: k.split("=")[1]
        for k in unquote(environ["QUERY_STRING"]).strip().split("&")
    }
    try:
        room = (
            Room.select().join(User).where((Room.name == ref["room"])
                                           & (User.name == ref["user"]))[0])
    except IndexError:
        return False
    else:
        for pr in room.players:
            if pr.player == user:
                if pr.role != Role.DM and room.is_locked:
                    return False
                break
        else:
            return False

    pr = PlayerRoom.get(room=room, player=user)
    await game_state.add_sid(sid, pr)

    logger.info(f"User {user.name} connected with identifier {sid}")

    sio.enter_room(sid, pr.active_location.get_path(), namespace=GAME_NS)
Example #8
0
async def set_player_role(sid: str, data: PlayerRoleChange):
    pr: PlayerRoom = game_state.get(sid)

    if pr.role != Role.DM:
        logger.warning(
            f"{pr.player.name} attempted to change the role of a player")
        return

    new_role = Role(data["role"])

    player_pr: PlayerRoom = PlayerRoom.get(player=data["player"], room=pr.room)
    creator: User = player_pr.room.creator

    if pr.player != creator and creator == player_pr.player:
        logger.warning(
            f"{pr.player.name} attempted to change the role of the campaign creator"
        )
        return

    player_pr.role = new_role
    player_pr.save()

    for sid in game_state.get_sids(player=player_pr.player, room=pr.room):
        await sio.disconnect(sid, namespace=GAME_NS)

    for psid in game_state.get_sids(room=pr.room):
        if game_state.get(psid).role == Role.DM:
            await sio.emit("Player.Role.Set",
                           data,
                           room=psid,
                           namespace=GAME_NS)
Example #9
0
async def set_info(request: web.Request):
    user: User = await check_authorized(request)

    creator = request.match_info["creator"]
    roomname = request.match_info["roomname"]

    data = await request.json()

    rooms = (
        PlayerRoom.select()
        .join(Room)
        .join(User)
        .filter(player=user)
        .where((User.name == creator) & (Room.name == roomname))
    )

    if len(rooms) != 1:
        return web.HTTPNotFound()

    room = rooms[0]

    if "notes" in data:
        room.notes = data["notes"]
    room.save()

    return web.HTTPOk()
Example #10
0
async def get_info(request: web.Request):
    user: User = await check_authorized(request)

    creator = request.match_info["creator"]
    roomname = request.match_info["roomname"]

    room = (
        PlayerRoom.select()
        .join(Room)
        .join(User)
        .filter(player=user)
        .where((User.name == creator) & (Room.name == roomname))
    )

    if len(room) != 1:
        return web.HTTPNotFound()

    return web.json_response(
        {
            "notes": room[0].notes,
            "last_played": None
            if room[0].last_played is None
            else room[0].last_played.strftime("%Y/%m/%d"),
        }
    )
Example #11
0
async def delete(request: web.Request):
    user: User = await check_authorized(request)

    creator = request.match_info["creator"]
    roomname = request.match_info["roomname"]

    if creator == user.name:
        room: Room = Room.get_or_none(name=roomname, creator=user)
        if room is None:
            return web.HTTPBadRequest()

        room.delete_instance(True)
        return web.HTTPOk()
    else:
        pr = (
            PlayerRoom.select()
            .join(Room)
            .join(User)
            .filter(player=user)
            .where((User.name == creator) & (Room.name == roomname))
        )
        if len(pr) == 1:
            pr[0].delete_instance(True)
            return web.HTTPOk()

    return web.HTTPUnauthorized()
async def create(request):
    user = await check_authorized(request)
    data = await request.json()
    roomname = data["name"]
    if not roomname:
        return web.HTTPBadRequest()
    else:
        with db.atomic():
            default_options = LocationOptions.create()
            room = Room.create(name=roomname,
                               creator=user,
                               default_options=default_options)
            loc = Location.create(room=room, name="start", index=1)
            loc.create_floor()
            PlayerRoom.create(player=user,
                              room=room,
                              role=Role.DM,
                              active_location=loc)
            room.save()
        return web.HTTPOk()
Example #13
0
async def add_shape_owner(sid: str, data: ServerShapeOwner):
    pr: PlayerRoom = game_state.get(sid)

    try:
        shape = Shape.get(uuid=data["shape"])
    except Shape.DoesNotExist as exc:
        logger.warning(
            f"Attempt to add owner to unknown shape by {pr.player.name} [{data['shape']}]"
        )
        raise exc

    if not has_ownership(shape, pr):
        logger.warning(
            f"{pr.player.name} attempted to change asset ownership of a shape it does not own"
        )
        return

    target_user = User.by_name(data["user"])
    if target_user is None:
        logger.warning(
            f"Attempt to add unknown user as owner to shape by {pr.player.name} [{data['user']}]"
        )
        return

    # Adding the DM as user is redundant and can only lead to confusion
    if PlayerRoom.get(room=pr.room, player=target_user).role == Role.DM:
        return

    if not ShapeOwner.get_or_none(shape=shape, user=target_user):
        ShapeOwner.create(
            shape=shape,
            user=target_user,
            edit_access=data["edit_access"],
            movement_access=data["movement_access"],
            vision_access=data["vision_access"],
        )
    await send_client_initiatives(pr, target_user)
    await sio.emit(
        "Shape.Owner.Add",
        data,
        room=pr.active_location.get_path(),
        skip_sid=sid,
        namespace=GAME_NS,
    )
    if not (shape.default_vision_access or shape.default_edit_access):
        for sid in game_state.get_sids(player=target_user,
                                       active_location=pr.active_location):
            await sio.emit(
                "Shape.Set",
                shape.as_dict(target_user, False),
                room=sid,
                namespace=GAME_NS,
            )
Example #14
0
async def kick_player(sid: int, player_id: int):
    pr: PlayerRoom = game_state.get(sid)

    if pr.role != Role.DM:
        logger.warning(f"{pr.player.name} attempted to refresh the invitation code.")
        return

    pr = PlayerRoom.get_or_none(player=player_id, room=pr.room)
    if pr:
        for psid in game_state.get_sids(player=pr.player, room=pr.room):
            await sio.disconnect(psid, namespace=GAME_NS)
        pr.delete_instance(True)
Example #15
0
async def kick_player(sid, playerId):
    sid_data = state.sid_map[sid]
    user = sid_data["user"]
    room = sid_data["room"]

    if room.creator != user:
        logger.warning(
            f"{user.name} attempted to refresh the invitation code.")
        return

    pr = PlayerRoom.get_or_none(player=playerId, room=room)
    if pr:
        for psid in state.get_sids(user=pr.player, room=room):
            await sio.disconnect(psid, namespace="/planarally")
        pr.delete_instance(True)
Example #16
0
async def kick_player(sid: str, player_id: int):
    pr: PlayerRoom = game_state.get(sid)

    if pr.role != Role.DM:
        logger.warning(f"{pr.player.name} attempted to refresh the invitation code.")
        return

    pr = PlayerRoom.get_or_none(player=player_id, room=pr.room)
    if pr is None:
        return

    creator: User = pr.room.creator

    if pr.player != creator and creator == pr.player:
        logger.warning(f"{pr.player.name} attempted to kick the campaign creator")
        return

    for psid in game_state.get_sids(player=pr.player, room=pr.room):
        await sio.disconnect(psid, namespace=GAME_NS)
    pr.delete_instance(True)
Example #17
0
async def update_client_location(player: int, room: int, sid: str,
                                 data: LocationOptions):
    pr = PlayerRoom.get(player=player, room=room)

    LocationUserOption.update(
        pan_x=data["pan_x"],
        pan_y=data["pan_y"],
        zoom_display=data["zoom_display"],
    ).where((LocationUserOption.location == pr.active_location)
            & (LocationUserOption.user == pr.player)).execute()

    if pr.role != Role.DM:
        for p_sid, p_player in game_state.get_t(skip_sid=sid):
            if p_player.role == Role.DM or p_player.player.id == player:
                await sio.emit(
                    "Client.Move",
                    {
                        "player": pr.player.id,
                        **data
                    },
                    room=p_sid,
                    namespace=GAME_NS,
                )
Example #18
0
async def connect(sid, environ):
    user = await authorized_userid(environ["aiohttp.request"])
    if user is None:
        await sio.emit("redirect", "/", room=sid, namespace="/planarally")
    else:
        ref = {
            k.split("=")[0]: k.split("=")[1]
            for k in unquote(environ["QUERY_STRING"]).strip().split("&")
        }
        try:
            room = (
                Room.select()
                .join(User)
                .where((Room.name == ref["room"]) & (User.name == ref["user"]))[0]
            )
        except IndexError:
            return False
        else:
            for pr in room.players:
                if pr.player == user:
                    if pr.role != Role.DM and room.is_locked:
                        return False
                    break
            else:
                return False

        pr = PlayerRoom.get(room=room, player=user)

        # todo: just store PlayerRoom as it has all the info
        await game_state.add_sid(sid, pr)

        logger.info(f"User {user.name} connected with identifier {sid}")

        labels = Label.select().where((Label.user == user) | (Label.visible == True))
        label_filters = LabelSelection.select().where(
            (LabelSelection.user == user) & (LabelSelection.room == room)
        )

        sio.enter_room(sid, pr.active_location.get_path(), namespace="/planarally")
        await sio.emit("Username.Set", user.name, room=sid, namespace="/planarally")
        await sio.emit(
            "Labels.Set",
            [l.as_dict() for l in labels],
            room=sid,
            namespace="/planarally",
        )
        await sio.emit(
            "Labels.Filters.Set",
            [l.label.uuid for l in label_filters],
            room=sid,
            namespace="/planarally",
        )
        await sio.emit(
            "Room.Info.Set",
            {
                "name": room.name,
                "creator": room.creator.name,
                "invitationCode": str(room.invitation_code),
                "isLocked": room.is_locked,
                "default_options": room.default_options.as_dict(),
                "players": [
                    {
                        "id": rp.player.id,
                        "name": rp.player.name,
                        "location": rp.active_location.id,
                    }
                    for rp in room.players
                ],
            },
            room=sid,
            namespace="/planarally",
        )
        await sio.emit(
            "Asset.List.Set",
            Asset.get_user_structure(user),
            room=sid,
            namespace="/planarally",
        )
        if pr.role == Role.DM:
            await sio.emit(
                "Locations.Settings.Set",
                {
                    l.name: {} if l.options is None else l.options.as_dict()
                    for l in pr.room.locations
                },
                room=sid,
                namespace="/planarally",
            )
        await load_location(sid, pr.active_location)