Ejemplo n.º 1
0
async def add_shape(sid, data):
    sid_data = state.sid_map[sid]
    user = sid_data["user"]
    room = sid_data["room"]
    location = sid_data["location"]

    if "temporary" not in data:
        data["temporary"] = False

    floor = location.floors.select().where(
        Floor.name == data["shape"]["floor"])[0]
    layer = floor.layers.where(Layer.name == data["shape"]["layer"])[0]

    if room.creator != user and not layer.player_editable:
        logger.warning(f"{user.name} attempted to add a shape to a dm layer")
        return
    if data["temporary"]:
        state.add_temp(sid, data["shape"]["uuid"])
    else:
        with db.atomic():
            data["shape"]["layer"] = layer
            data["shape"]["index"] = layer.shapes.count()
            # Shape itself
            shape = Shape.create(**reduce_data_to_model(Shape, data["shape"]))
            # Subshape
            type_table = get_table(shape.type_)
            type_table.create(shape=shape,
                              **reduce_data_to_model(type_table,
                                                     data["shape"]))
            # Owners
            ShapeOwner.create(shape=shape, user=user)
            # Trackers
            for tracker in data["shape"]["trackers"]:
                Tracker.create(**reduce_data_to_model(Tracker, tracker),
                               shape=shape)
            # Auras
            for aura in data["shape"]["auras"]:
                Aura.create(**reduce_data_to_model(Aura, aura), shape=shape)

    if layer.player_visible:
        for room_player in room.players:
            for psid in state.get_sids(user=room_player.player, room=room):
                if psid == sid:
                    continue
                if not data["temporary"]:
                    data["shape"] = shape.as_dict(room_player.player, False)
                await sio.emit("Shape.Add",
                               data["shape"],
                               room=psid,
                               namespace="/planarally")

    for csid in state.get_sids(user=room.creator, room=room):
        if csid == sid:
            continue
        if not data["temporary"]:
            data["shape"] = shape.as_dict(room.creator, True)
        await sio.emit("Shape.Add",
                       data["shape"],
                       room=csid,
                       namespace="/planarally")
Ejemplo n.º 2
0
async def change_location(sid, location):
    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 change location")
        return

    old_location = room.get_active_location(dm=True)
    sio.leave_room(sid, old_location.get_path(), namespace="/planarally")
    room.dm_location = location
    new_location = room.get_active_location(dm=True)

    sio.enter_room(sid, new_location.get_path(), namespace="/planarally")
    await load_location(sid, new_location)

    room.player_location = location

    for room_player in room.players:
        for psid in state.get_sids(user=room_player.player, room=room):
            sio.leave_room(psid,
                           old_location.get_path(),
                           namespace="/planarally")
            sio.enter_room(psid,
                           new_location.get_path(),
                           namespace="/planarally")
            await load_location(psid, new_location)
Ejemplo n.º 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='')}"
        })
Ejemplo n.º 4
0
async def add(sid, data):
    sid_data = state.sid_map[sid]
    user = sid_data["user"]
    room = sid_data["room"]
    location = sid_data["location"]

    label = Label.get_or_none(uuid=data)

    if label is not None:
        logger.warn(
            f"{user.name} tried to add a label with an id that already exists."
        )
        return

    if data["user"] != user.name:
        logger.warn(f"{user.name} tried to add a label for someone else.")
        return

    data["user"] = User.by_name(data["user"])
    label = Label.create(**data)

    for psid in state.get_sids(skip_sid=sid, room=room):
        if state.get_user(psid) == user or label.visible:
            await sio.emit("Label.Add",
                           label.as_dict(),
                           room=psid,
                           namespace="/planarally")
Ejemplo n.º 5
0
async def remove_shape(sid, data):
    sid_data = state.sid_map[sid]
    user = sid_data["user"]
    room = sid_data["room"]
    location = sid_data["location"]

    # We're first gonna retrieve the existing server side shape for some validation checks
    if data["temporary"]:
        # This stuff is not stored so we cannot do any server side validation /shrug
        shape = data["shape"]
        layer = location.layers.where(Layer.name == data["shape"]["layer"])[0]
    else:
        # Use the server version of the shape.
        try:
            shape = Shape.get(uuid=data["shape"]["uuid"])
        except Shape.DoesNotExist:
            logger.warning(f"Attempt to update unknown shape by {user.name}")
            return
        layer = shape.layer

    # Ownership validatation
    if room.creator != user:
        if not layer.player_editable:
            logger.warning(
                f"{user.name} attempted to remove a shape on a dm layer")
            return

        if data["temporary"]:
            if user.name not in shape["owners"]:
                logger.warning(
                    f"{user.name} attempted to remove asset it does not own")
                return
        else:
            if not ShapeOwner.get_or_none(shape=shape, user=user):
                logger.warning(
                    f"{user.name} attempted to remove asset it does not own")
                return

    if data["temporary"]:
        state.remove_temp(sid, data["shape"]["uuid"])
    else:
        shape.delete_instance()

    if layer.player_visible:
        await sio.emit(
            "Shape.Remove",
            data["shape"],
            room=location.get_path(),
            skip_sid=sid,
            namespace="/planarally",
        )
    else:
        for csid in state.get_sids(user=room.creator, room=room):
            if csid == sid:
                continue
            await sio.emit("Shape.Remove",
                           data["shape"],
                           room=csid,
                           namespace="/planarally")
Ejemplo n.º 6
0
async def send_client_initiatives(room, location, user=None, skip_sid=None):
    for room_player in room.players:
        if user is None or user == room_player.player:
            for psid in state.get_sids(user=room_player.player, room=room):
                if psid == skip_sid:
                    continue
                await sio.emit(
                    "Initiative.Set",
                    get_client_initiatives(room_player.player, location),
                    room=psid,
                    namespace="/planarally",
                )

    if user is None or user == room.creator:
        for csid in state.get_sids(user=room.creator, room=room):
            if csid == skip_sid:
                continue
            await sio.emit(
                "Initiative.Set",
                get_client_initiatives(room.creator, location),
                room=csid,
                namespace="/planarally",
            )
Ejemplo n.º 7
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)
Ejemplo n.º 8
0
async def add_filter(sid, uuid):
    sid_data = state.sid_map[sid]
    user = sid_data["user"]
    room = sid_data["room"]

    label = Label.get_or_none(uuid=uuid)

    LabelSelection.create(label=label, user=user, room=room)

    for psid in state.get_sids(skip_sid=sid, room=room):
        if state.get_user(psid) == user:
            await sio.emit("Labels.Filter.Add",
                           uuid,
                           room=psid,
                           namespace="/planarally")
Ejemplo n.º 9
0
async def move_shape_order(sid, data):
    sid_data = state.sid_map[sid]
    user = sid_data["user"]
    room = sid_data["room"]
    location = sid_data["location"]

    shape = Shape.get(uuid=data["shape"]["uuid"])
    layer = shape.layer

    if room.creator != user and not layer.player_editable:
        logger.warning(
            f"{user.name} attempted to move a shape order on a dm layer")
        return

    target = data["index"] + 1
    sign = 1 if target <= 1 else -1
    polarity = 1 if shape.index > 0 else -1
    case = Case(
        None,
        (
            (Shape.index == shape.index, target * (-polarity)),
            (
                (polarity * sign * Shape.index) <
                (polarity * sign * shape.index),
                (Shape.index + (polarity * sign * 1)) * -1,
            ),
        ),
        Shape.index * -1,
    )
    Shape.update(index=case).where(Shape.layer == layer).execute()
    if layer.player_visible:
        await sio.emit(
            "Shape.Order.Set",
            data,
            room=location.get_path(),
            skip_sid=sid,
            namespace="/planarally",
        )
    else:
        for csid in state.get_sids(user=room.creator, room=room):
            if csid == sid:
                continue
            await sio.emit("Shape.Order.Set",
                           data["shape"],
                           room=csid,
                           namespace="/planarally")
Ejemplo n.º 10
0
async def remove_filter(sid, uuid):
    sid_data = state.sid_map[sid]
    user = sid_data["user"]
    room = sid_data["room"]

    label = Label.get_or_none(uuid=uuid)

    ls = LabelSelection.get_or_none(label=label, room=room, user=user)

    if ls:
        ls.delete_instance(True)

    for psid in state.get_sids(skip_sid=sid, room=room):
        if state.get_user(psid) == user:
            await sio.emit("Labels.Filter.Remove",
                           uuid,
                           room=psid,
                           namespace="/planarally")
Ejemplo n.º 11
0
async def set_visibility(sid, data):
    sid_data = state.sid_map[sid]
    user = sid_data["user"]
    room = sid_data["room"]
    location = sid_data["location"]

    label = Label.get_or_none(uuid=data["uuid"])

    if label is None:
        logger.warn(f"{user.name} tried to change a non-existing label.")
        return

    if label.user != user:
        logger.warn(f"{user.name} tried to change another user's label.")
        return

    label.visible = data["visible"]
    label.save()

    for psid in state.get_sids(skip_sid=sid, room=room):
        if state.get_user(psid) == user:
            await sio.emit(
                "Label.Visibility.Set",
                {
                    "user": label.user.name,
                    **data
                },
                room=psid,
                namespace="/planarally",
            )
        else:
            if data["visible"]:
                await sio.emit("Label.Add",
                               label.as_dict(),
                               room=psid,
                               namespace="/planarally")
            else:
                await sio.emit("Label.Delete", {
                    'uuid': label.uuid,
                    'user': label.user.name
                },
                               room=psid,
                               namespace="/planarally")
Ejemplo n.º 12
0
async def update_shape(sid, data):
    sid_data = state.sid_map[sid]
    user = sid_data["user"]
    room = sid_data["room"]
    location = sid_data["location"]

    # We're first gonna retrieve the existing server side shape for some validation checks
    if data["temporary"]:
        # This stuff is not stored so we cannot do any server side validation /shrug
        shape = data["shape"]
        layer = location.layers.where(Layer.name == data["shape"]["layer"])[0]
    else:
        # Use the server version of the shape.
        try:
            shape = Shape.get(uuid=data["shape"]["uuid"])
        except Shape.DoesNotExist:
            logger.warning(f"Attempt to update unknown shape by {user.name}")
            return
        layer = shape.layer

    # Ownership validatation
    if room.creator != user:
        if not layer.player_editable:
            logger.warning(
                f"{user.name} attempted to move a shape on a dm layer")
            return

        if data["temporary"]:
            if user.name not in shape["owners"]:
                logger.warning(
                    f"{user.name} attempted to move asset it does not own")
                return
        else:
            if not ShapeOwner.get_or_none(shape=shape, user=user):
                logger.warning(
                    f"{user.name} attempted to move asset it does not own")
                return

    # Overwrite the old data with the new data
    if not data["temporary"]:
        with db.atomic():
            data["shape"]["layer"] = Layer.get(location=location,
                                               name=data["shape"]["layer"])
            # Otherwise backrefs can cause errors as they need to be handled separately
            update_model_from_dict(shape,
                                   reduce_data_to_model(Shape, data["shape"]))
            shape.save()
            type_table = get_table(shape.type_)
            type_instance = type_table.get(uuid=shape.uuid)
            # no backrefs on these tables
            update_model_from_dict(type_instance,
                                   data["shape"],
                                   ignore_unknown=True)
            type_instance.save()

            old_owners = {owner.user.name for owner in shape.owners}
            new_owners = set(data["shape"]["owners"])
            for owner in old_owners ^ new_owners:
                if owner == "":
                    continue
                delta_owner = User.by_name(owner)
                if owner in new_owners:
                    ShapeOwner.create(shape=shape, user=delta_owner)
                else:
                    ShapeOwner.get(shape=shape,
                                   user=delta_owner).delete_instance(True)
                await send_client_initiatives(room, location, delta_owner)

    # Send to players
    if layer.player_visible:
        for room_player in room.players:
            for psid in state.get_sids(user=room_player.player, room=room):
                if psid == sid:
                    continue
                if not data["temporary"]:
                    data["shape"] = shape.as_dict(room_player.player, False)
                await sio.emit("Shape.Update",
                               data,
                               room=psid,
                               namespace="/planarally")

    # Send to DM
    for csid in state.get_sids(user=room.creator, room=room):
        if csid == sid:
            continue
        if not data["temporary"]:
            data["shape"] = shape.as_dict(room.creator, True)
        await sio.emit("Shape.Update",
                       data,
                       room=csid,
                       namespace="/planarally")
Ejemplo n.º 13
0
async def change_shape_layer(sid, data):
    sid_data = state.sid_map[sid]
    user = sid_data["user"]
    room = sid_data["room"]
    location = sid_data["location"]

    if room.creator != user:
        logger.warning(f"{user.name} attempted to move the layer of a shape")
        return

    layer = Layer.get(location=location, name=data["layer"])
    shape = Shape.get(uuid=data["uuid"])
    old_layer = shape.layer
    old_index = shape.index

    if old_layer.player_visible and not layer.player_visible:
        for room_player in room.players:
            for psid in state.get_sids(user=room_player.player, room=room):
                if psid == sid:
                    continue
                await sio.emit(
                    "Shape.Remove",
                    shape.as_dict(room_player.player, False),
                    room=psid,
                    namespace="/planarally",
                )

    shape.layer = layer
    shape.index = layer.shapes.count()
    shape.save()
    Shape.update(index=Shape.index -
                 1).where((Shape.layer == old_layer)
                          & (Shape.index >= old_index)).execute()

    if old_layer.player_visible and layer.player_visible:
        await sio.emit(
            "Shape.Layer.Change",
            data,
            room=location.get_path(),
            skip_sid=sid,
            namespace="/planarally",
        )
    else:
        for csid in state.get_sids(user=room.creator, room=room):
            if csid == sid:
                continue
            await sio.emit(
                "Shape.Layer.Change",
                data,
                room=location.get_path(),
                skip_sid=sid,
                namespace="/planarally",
            )
        if layer.player_visible:
            for room_player in room.players:
                for psid in state.get_sids(user=room_player.player, room=room):
                    if psid == sid:
                        continue
                    await sio.emit(
                        "Shape.Add",
                        shape.as_dict(room_player.player, False),
                        room=psid,
                        namespace="/planarally",
                    )