Exemple #1
0
async def change_shape_floor(sid: int, data: Dict[str, Any]):
    pr: PlayerRoom = game_state.get(sid)

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

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

    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()

    await sio.emit(
        "Shape.Floor.Change",
        data,
        room=pr.active_location.get_path(),
        skip_sid=sid,
        namespace=GAME_NS,
    )
Exemple #2
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
    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()

    await sio.emit(
        "Shape.Layer.Change",
        data,
        room=location.get_path(),
        skip_sid=sid,
        namespace="/planarally",
    )
Exemple #3
0
async def update_shape_position(sid, data):
    sid_data = state.sid_map[sid]
    user = sid_data["user"]
    room = sid_data["room"]
    location = sid_data["location"]

    shape, layer = await _get_shape(data, location, user)

    if not await has_ownership(layer, room, data, user, shape):
        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"])
            # Shape
            model = reduce_data_to_model(Shape, data["shape"])
            update_model_from_dict(shape, model)
            shape.save()
            if shape.type_ == "polygon":
                # Subshape
                type_instance = shape.subtype
                # no backrefs on these tables
                type_instance.update_from_dict(data["shape"],
                                               ignore_unknown=True)
                type_instance.save()

    await sync_shape_update(layer, room, data, sid, shape)
Exemple #4
0
async def change_shape_floor(sid: str, data: ShapeFloorChange):
    pr: PlayerRoom = game_state.get(sid)

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

    floor: Floor = Floor.get(location=pr.active_location, name=data["floor"])
    shapes: List[Shape] = [s for s in Shape.select().where(Shape.uuid << data["uuids"])]
    layer: Layer = Layer.get(floor=floor, name=shapes[0].layer.name)
    old_layer = shapes[0].layer

    for shape in shapes:
        old_index = shape.index
        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()

    await sio.emit(
        "Shapes.Floor.Change",
        data,
        room=pr.active_location.get_path(),
        skip_sid=sid,
        namespace=GAME_NS,
    )
Exemple #5
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

    layer = location.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.get(location=location,
                                               name=data["shape"]["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")
Exemple #6
0
async def set_gridsize(sid, grid_size):
    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 set gridsize without DM rights")
        return
    gl = GridLayer[Layer.get(location=location, name="grid")]
    gl.size = grid_size
    gl.save()
    await sio.emit(
        "Gridsize.Set",
        grid_size,
        room=location.get_path(),
        skip_sid=sid,
        namespace="/planarally",
    )
Exemple #7
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"])
    shape.layer = layer
    shape.save()

    await sio.emit(
        "Shape.Layer.Change",
        data,
        room=location.get_path(),
        skip_sid=sid,
        namespace="/planarally",
    )
Exemple #8
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")
Exemple #9
0
async def change_shape_layer(sid: int, data: Dict[str, Any]):
    pr: PlayerRoom = game_state.get(sid)

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

    floor = Floor.get(location=pr.active_location, name=data["floor"])
    layer = Layer.get(floor=floor, 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 pr.room.players:
            if room_player.role == Role.DM:
                continue
            for psid in game_state.get_sids(
                    player=room_player.player,
                    active_location=pr.active_location):
                if psid == sid:
                    continue
                await sio.emit(
                    "Shape.Remove",
                    shape.as_dict(room_player.player, False),
                    room=psid,
                    namespace=GAME_NS,
                )

    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=pr.active_location.get_path(),
            skip_sid=sid,
            namespace=GAME_NS,
        )
    else:
        for room_player in pr.room.players:
            is_dm = room_player.role == Role.DM
            for psid in game_state.get_sids(
                    player=room_player.player,
                    active_location=pr.active_location):
                if psid == sid:
                    continue
                if is_dm:
                    await sio.emit(
                        "Shape.Layer.Change",
                        data,
                        room=pr.active_location.get_path(),
                        skip_sid=sid,
                        namespace=GAME_NS,
                    )
                elif layer.player_visible:
                    await sio.emit(
                        "Shape.Add",
                        shape.as_dict(room_player.player, False),
                        room=psid,
                        namespace=GAME_NS,
                    )
Exemple #10
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",
                    )
Exemple #11
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"]

    shape, layer = await _get_shape(data, location, user)

    if not await has_ownership(layer, room, data, user, shape):
        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"])
            # Shape
            update_model_from_dict(shape,
                                   reduce_data_to_model(Shape, data["shape"]))
            shape.save()
            # Subshape
            type_instance = shape.subtype
            # no backrefs on these tables
            type_instance.update_from_dict(data["shape"], ignore_unknown=True)
            type_instance.save()
            # Owners
            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)
            # Trackers
            old_trackers = {tracker.uuid for tracker in shape.trackers}
            new_trackers = {
                tracker["uuid"]
                for tracker in data["shape"]["trackers"]
            }
            for tracker_id in old_trackers | new_trackers:
                remove = tracker_id in old_trackers - new_trackers
                if not remove:
                    tracker = next(tr for tr in data["shape"]["trackers"]
                                   if tr["uuid"] == tracker_id)
                    reduced = reduce_data_to_model(Tracker, tracker)
                    reduced["shape"] = shape
                if tracker_id in new_trackers - old_trackers:
                    Tracker.create(**reduced)
                    continue
                tracker_db = Tracker.get(uuid=tracker_id)
                if remove:
                    tracker_db.delete_instance(True)
                else:
                    update_model_from_dict(tracker_db, reduced)
                    tracker_db.save()

            # Auras
            old_auras = {aura.uuid for aura in shape.auras}
            new_auras = {aura["uuid"] for aura in data["shape"]["auras"]}
            for aura_id in old_auras | new_auras:
                remove = aura_id in old_auras - new_auras
                if not remove:
                    aura = next(au for au in data["shape"]["auras"]
                                if au["uuid"] == aura_id)
                    reduced = reduce_data_to_model(Aura, aura)
                    reduced["shape"] = shape
                if aura_id in new_auras - old_auras:
                    Aura.create(**reduced)
                    continue
                aura_db = Aura.get_or_none(uuid=aura_id)
                if remove:
                    aura_db.delete_instance(True)
                else:
                    update_model_from_dict(aura_db, reduced)
                    aura_db.save()
            # Labels
            for label in data["shape"]["labels"]:
                label_db = Label.get_or_none(uuid=label["uuid"])
                reduced = reduce_data_to_model(Label, label)
                reduced["user"] = User.by_name(reduced["user"])
                if label_db:
                    update_model_from_dict(label_db, reduced)
                    label_db.save()
                else:
                    Label.create(**reduced)
                shape_label_db = ShapeLabel.get_or_none(shape=shape,
                                                        label=label_db)
            old_labels = {
                shape_label.label.uuid
                for shape_label in shape.labels
            }
            new_labels = set(label["uuid"]
                             for label in data["shape"]["labels"])
            for label in old_labels ^ new_labels:
                if label == "":
                    continue
                if label in new_labels:
                    ShapeLabel.create(shape=shape, label=Label.get(uuid=label))
                else:
                    ShapeLabel.get(label=Label.get(uuid=label),
                                   shape=shape).delete_instance(True)

    await sync_shape_update(layer, room, data, sid, shape)
Exemple #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"]

    shape, layer = await _get_shape(data, location, user)

    if not await has_ownership(layer, room, data, user, shape):
        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"])
            # Shape
            update_model_from_dict(shape,
                                   reduce_data_to_model(Shape, data["shape"]))
            shape.save()
            # Subshape
            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()
            # Owners
            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)
            # Trackers
            for tracker in data["shape"]["trackers"]:
                tracker_db = Tracker.get_or_none(uuid=tracker["uuid"])
                reduced = reduce_data_to_model(Tracker, tracker)
                reduced["shape"] = shape
                if tracker_db:
                    update_model_from_dict(tracker_db, reduced)
                    tracker_db.save()
                else:
                    Tracker.create(**reduced)
            # Auras
            for aura in data["shape"]["auras"]:
                aura_db = Aura.get_or_none(uuid=aura["uuid"])
                reduced = reduce_data_to_model(Aura, aura)
                reduced["shape"] = shape
                if aura_db:
                    update_model_from_dict(aura_db, reduced)
                    aura_db.save()
                else:
                    Aura.create(**reduced)

    await sync_shape_update(layer, room, data, sid, shape)