Example #1
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 #2
0
async def change_location(sid: int, data: Dict[str, str]):
    pr: PlayerRoom = game_state.get(sid)

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

    # Send an anouncement to show loading state
    for room_player in pr.room.players:
        if not room_player.player.name in data["users"]:
            continue

        for psid in game_state.get_sids(player=room_player.player, room=pr.room):
            await sio.emit("Location.Change.Start", room=psid, namespace="/planarally")

    new_location = Location[data["location"]]

    for room_player in pr.room.players:
        if not room_player.player.name in data["users"]:
            continue

        for psid in game_state.get_sids(player=room_player.player, room=pr.room):
            sio.leave_room(
                psid, room_player.active_location.get_path(), namespace="/planarally"
            )
            sio.enter_room(psid, new_location.get_path(), namespace="/planarally")
            await load_location(psid, new_location)
        room_player.active_location = new_location
        room_player.save()
Example #3
0
async def change_location(sid: str, data: LocationChangeData):
    pr: PlayerRoom = game_state.get(sid)

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

    # Send an anouncement to show loading state
    for room_player in pr.room.players:
        if not room_player.player.name in data["users"]:
            continue

        for psid in game_state.get_sids(player=room_player.player,
                                        room=pr.room):
            await sio.emit("Location.Change.Start",
                           room=psid,
                           namespace=GAME_NS)

    new_location = Location.get_by_id(data["location"])

    for room_player in pr.room.players:
        if not room_player.player.name in data["users"]:
            continue

        for psid in game_state.get_sids(player=room_player.player,
                                        room=pr.room):
            try:
                sio.leave_room(psid,
                               room_player.active_location.get_path(),
                               namespace=GAME_NS)
                sio.enter_room(psid,
                               new_location.get_path(),
                               namespace=GAME_NS)
            except KeyError:
                await game_state.remove_sid(psid)
                continue
            await load_location(psid, new_location)
            # We could send this to all users in the new location, BUT
            # loading times might vary and we don't want to snap people back when they already move around
            # And it's possible that there are already users on the new location that don't want to be moved to this new position
            if "position" in data:
                await sio.emit(
                    "Position.Set",
                    data=data["position"],
                    room=psid,
                    namespace=GAME_NS,
                )
        room_player.active_location = new_location
        room_player.save()
Example #4
0
def get_owner_sids(pr: PlayerRoom,
                   shape: Shape,
                   skip_sid=None) -> Generator[str, None, None]:
    for psid in game_state.get_sids(active_location=pr.active_location,
                                    skip_sid=skip_sid):
        if has_ownership(shape, game_state.get(psid)):
            yield psid
Example #5
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 #6
0
async def set_name_visible(sid: str, data: ShapeSetBooleanValue):
    pr: PlayerRoom = game_state.get(sid)

    shape = get_shape_or_none(pr, data["shape"], "NameVisible.Set")
    if shape is None:
        return

    shape.name_visible = data["value"]
    shape.save()

    owners = [*get_owner_sids(pr, shape, skip_sid=sid)]

    await sio.emit(
        "Shape.Options.NameVisible.Set",
        data,
        skip_sid=sid,
        room=pr.active_location.get_path(),
        namespace=GAME_NS,
    )

    for psid in game_state.get_sids(active_location=pr.active_location,
                                    skip_sid=sid):
        if psid in owners:
            continue
        await sio.emit(
            "Shape.Options.Name.Set",
            {
                "shape": shape.uuid,
                "value": shape.name if data["value"] else "?"
            },
            room=psid,
            namespace=GAME_NS,
        )
Example #7
0
async def create_aura(sid: str, data: AuraDelta):
    pr: PlayerRoom = game_state.get(sid)

    shape = get_shape_or_none(pr, data["shape"], "Aura.Create")
    if shape is None:
        return

    model = reduce_data_to_model(Aura, data)
    aura = Aura.create(**model)
    aura.save()

    owners = [*get_owner_sids(pr, shape, skip_sid=sid)]
    for psid in owners:
        await sio.emit(
            "Shape.Options.Aura.Create", data, room=psid, namespace=GAME_NS,
        )
    if aura.visible:
        for psid in game_state.get_sids(
            active_location=pr.active_location, skip_sid=sid
        ):
            if psid in owners:
                continue
            await sio.emit(
                "Shape.Options.Aura.Create", data, room=psid, namespace=GAME_NS,
            )
Example #8
0
async def refresh_invite_code(sid: str):
    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.room.invitation_code = uuid.uuid4()
    pr.room.save()

    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,
        ):
            await sio.emit(
                "Room.Info.InvitationCode.Set",
                str(pr.room.invitation_code),
                room=psid,
                namespace=GAME_NS,
            )
Example #9
0
async def add_shape(sid: int, data: Dict[str, Any]):
    pr: PlayerRoom = game_state.get(sid)

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

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

    if pr.role != Role.DM and not layer.player_editable:
        logger.warning(
            f"{pr.player.name} attempted to add a shape to a dm layer")
        return
    if data["temporary"]:
        game_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,
                **type_table.pre_create(
                    **reduce_data_to_model(type_table, data["shape"])),
            )
            # Owners
            for owner in data["shape"]["owners"]:
                ShapeOwner.create(
                    shape=shape,
                    user=User.by_name(owner["user"]),
                    edit_access=owner["edit_access"],
                    movement_access=owner["movement_access"],
                    vision_access=owner["vision_access"],
                )
            # 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)

    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 not is_dm and not layer.player_visible:
                continue
            if not data["temporary"]:
                data["shape"] = shape.as_dict(room_player.player, is_dm)
            await sio.emit("Shape.Add",
                           data["shape"],
                           room=psid,
                           namespace=GAME_NS)
Example #10
0
async def remove_shape(sid: int, data: Dict[str, Any]):
    pr: PlayerRoom = game_state.get(sid)

    # We're first gonna retrieve the existing server side shape for some validation checks
    if data["temporary"]:
        if not has_ownership_temp(data["shape"], pr):
            logger.warning(
                f"User {pr.player.name} tried to update a shape it does not own."
            )
            return

        # This stuff is not stored so we cannot do any server side validation /shrug
        shape = data["shape"]
        floor = pr.active_location.floors.select().where(
            Floor.name == data["shape"]["floor"])[0]
        layer = floor.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 {pr.player.name}")
            return
        layer = shape.layer

        if not has_ownership(shape, pr):
            logger.warning(
                f"User {pr.player.name} tried to update a shape it does not own."
            )
            return

    if data["temporary"]:
        game_state.remove_temp(sid, data["shape"]["uuid"])
    else:
        old_index = shape.index
        shape.delete_instance(True)
        Shape.update(index=Shape.index -
                     1).where((Shape.layer == layer)
                              & (Shape.index >= old_index)).execute()

    if layer.player_visible:
        await sio.emit(
            "Shape.Remove",
            data["shape"],
            room=pr.active_location.get_path(),
            skip_sid=sid,
            namespace=GAME_NS,
        )
    else:
        for csid in game_state.get_sids(player=pr.room.creator,
                                        active_location=pr.active_location):
            if csid == sid:
                continue
            await sio.emit("Shape.Remove",
                           data["shape"],
                           room=csid,
                           namespace=GAME_NS)
Example #11
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 target_user == pr.room.creator:
        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 #12
0
async def set_locked_game_state(sid: str, is_locked: bool):
    pr: PlayerRoom = game_state.get(sid)

    if pr.role != Role.DM:
        logger.warning(f"{pr.player.name} attempted to set the locked game_state.")
        return

    pr.room.is_locked = is_locked
    pr.room.save()
    for psid in game_state.get_sids(room=pr.room):
        if game_state.get(psid).role != Role.DM:
            await sio.disconnect(psid, namespace=GAME_NS)
Example #13
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)
async def update_aura(sid: str, data: AuraDelta):
    pr: PlayerRoom = game_state.get(sid)

    shape = get_shape_or_none(pr, data["shape"], "Aura.Update")
    if shape is None:
        return

    aura = Aura.get_by_id(data["uuid"])
    changed_visible = aura.visible != data.get("visible", aura.visible)
    update_model_from_dict(aura, data)
    aura.save()

    owners = [*get_owner_sids(pr, shape, skip_sid=sid)]
    for psid in owners:
        await sio.emit(
            "Shape.Options.Aura.Update",
            data,
            room=psid,
            namespace=GAME_NS,
        )
    for psid in game_state.get_sids(active_location=pr.active_location,
                                    skip_sid=sid):
        if psid in owners:
            continue
        if changed_visible:
            if aura.visible:
                await sio.emit(
                    "Shape.Options.Aura.Create",
                    {
                        "shape": shape.uuid,
                        **aura.as_dict()
                    },
                    room=psid,
                    namespace=GAME_NS,
                )
            else:
                await sio.emit(
                    "Shape.Options.Aura.Remove",
                    {
                        "shape": shape.uuid,
                        "value": aura.uuid
                    },
                    room=psid,
                    namespace=GAME_NS,
                )
        else:
            await sio.emit(
                "Shape.Options.Aura.Update",
                data,
                room=psid,
                namespace=GAME_NS,
            )
async def update_tracker(sid: str, data: TrackerDelta):
    pr: PlayerRoom = game_state.get(sid)

    shape = get_shape_or_none(pr, data["shape"], "Tracker.Update")
    if shape is None:
        return

    tracker = Tracker.get_by_id(data["uuid"])
    changed_visible = tracker.visible != data.get("visible", tracker.visible)
    update_model_from_dict(tracker, data)
    tracker.save()

    owners = [*get_owner_sids(pr, shape, skip_sid=sid)]
    for psid in owners:
        await sio.emit(
            "Shape.Options.Tracker.Update",
            data,
            room=psid,
            namespace=GAME_NS,
        )
    for psid in game_state.get_sids(active_location=pr.active_location,
                                    skip_sid=sid):
        if psid in owners:
            continue
        if changed_visible:
            if tracker.visible:
                await sio.emit(
                    "Shape.Options.Tracker.Create",
                    {
                        "shape": shape.uuid,
                        **tracker.as_dict()
                    },
                    room=psid,
                    namespace=GAME_NS,
                )
            else:
                await sio.emit(
                    "Shape.Options.Tracker.Remove",
                    {
                        "shape": shape.uuid,
                        "value": tracker.uuid
                    },
                    room=psid,
                    namespace=GAME_NS,
                )
        else:
            await sio.emit(
                "Shape.Options.Tracker.Update",
                data,
                room=psid,
                namespace=GAME_NS,
            )
Example #16
0
async def add_filter(sid: str, uuid: str):
    pr: PlayerRoom = game_state.get(sid)

    label = Label.get_or_none(uuid=uuid)

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

    for psid in game_state.get_sids(skip_sid=sid, room=pr.room):
        if game_state.get_user(psid) == pr.player:
            await sio.emit("Labels.Filter.Add",
                           uuid,
                           room=psid,
                           namespace=GAME_NS)
Example #17
0
async def rename_location(sid: int, data: Dict[str, str]):
    pr: PlayerRoom = game_state.get(sid)

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

    location = Location[data["id"]]
    location.name = data["new"]
    location.save()

    for player_room in pr.room.players:
        for psid in game_state.get_sids(skip_sid=sid, player=player_room.player):
            await sio.emit("Location.Rename", data, room=psid, namespace="/planarally")
Example #18
0
async def send_client_initiatives(pr: PlayerRoom,
                                  target_user: User = None,
                                  skip_sid=None) -> None:
    for room_player in pr.room.players:
        if target_user is None or target_user == room_player.player:
            for psid in game_state.get_sids(player=room_player.player,
                                            room=pr.room):
                if psid == skip_sid:
                    continue
                await sio.emit(
                    "Initiative.Set",
                    get_client_initiatives(room_player.player,
                                           pr.active_location),
                    room=psid,
                    namespace="/planarally",
                )
Example #19
0
async def remove_filter(sid: str, uuid: str):
    pr: PlayerRoom = game_state.get(sid)

    label = Label.get_or_none(uuid=uuid)

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

    if ls:
        ls.delete_instance(True)

    for psid in game_state.get_sids(skip_sid=sid, room=pr.room):
        if game_state.get_user(psid) == pr.player:
            await sio.emit("Labels.Filter.Remove",
                           uuid,
                           room=psid,
                           namespace=GAME_NS)
Example #20
0
async def unarchive_location(sid: str, location_id: int):
    pr: PlayerRoom = game_state.get(sid)

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

    location = Location.get_by_id(location_id)
    location.archived = False
    location.save()

    for player_room in pr.room.players:
        for psid in game_state.get_sids(skip_sid=sid,
                                        player=player_room.player):
            await sio.emit("Location.Unarchive",
                           location_id,
                           room=psid,
                           namespace=GAME_NS)
Example #21
0
async def rename_location(sid: str, data: LocationRenameData):
    pr: PlayerRoom = game_state.get(sid)

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

    location = Location.get_by_id(data["location"])
    location.name = data["name"]
    location.save()

    for player_room in pr.room.players:
        for psid in game_state.get_sids(skip_sid=sid,
                                        player=player_room.player):
            await sio.emit("Location.Rename",
                           data,
                           room=psid,
                           namespace=GAME_NS)
Example #22
0
async def set_location_options(sid: str, data: LocationOptionsData):
    pr: PlayerRoom = game_state.get(sid)

    if pr.role != Role.DM:
        logger.warning(f"{pr.player.name} attempted to set a room option")
        return

    if data.get("location", None) is None:
        options = pr.room.default_options
    else:
        loc = Location.get_by_id(data["location"])
        if loc.options is None:
            loc.options = LocationOptions.create(
                unit_size=None,
                unit_size_unit=None,
                grid_type=None,
                use_grid=None,
                full_fow=None,
                fow_opacity=None,
                fow_los=None,
                vision_mode=None,
                vision_min_range=None,
                vision_max_range=None,
            )
            loc.save()
        options = loc.options

    update_model_from_dict(options, data["options"])
    options.save()

    if data.get("location", None) is None:
        for sid in game_state.get_sids(skip_sid=sid, room=pr.room):
            await sio.emit("Location.Options.Set",
                           data,
                           room=sid,
                           namespace=GAME_NS)
    else:
        await sio.emit(
            "Location.Options.Set",
            data,
            room=pr.active_location.get_path(),
            skip_sid=sid,
            namespace=GAME_NS,
        )
Example #23
0
async def set_visibility(sid: str, data: LabelVisibilityMessage):
    pr: PlayerRoom = game_state.get(sid)

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

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

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

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

    for psid in game_state.get_sids(skip_sid=sid, room=pr.room):
        if game_state.get_user(psid) == pr.player:
            await sio.emit(
                "Label.Visibility.Set",
                {
                    "user": label.pr.player.name,
                    **data
                },
                room=psid,
                namespace=GAME_NS,
            )
        else:
            if data["visible"]:
                await sio.emit("Label.Add",
                               label.as_dict(),
                               room=psid,
                               namespace=GAME_NS)
            else:
                await sio.emit(
                    "Label.Delete",
                    {
                        "uuid": label.uuid,
                        "user": label.user.name
                    },
                    room=psid,
                    namespace=GAME_NS,
                )
Example #24
0
async def set_locations_order(sid: int, locations: List[int]):
    pr: PlayerRoom = game_state.get(sid)

    if pr.role != Role.DM:
        logger.warning(f"{pr.player.name} attempted to reorder locations.")
        return

    for i, idx in enumerate(locations):
        l: Location = Location[idx]
        l.index = i + 1
        l.save()

    for player_room in pr.room.players:
        if player_room.role != Role.DM:
            continue
        for psid in game_state.get_sids(skip_sid=sid, player=player_room.player):
            await sio.emit(
                "Locations.Order.Set", locations, room=psid, namespace=GAME_NS
            )
Example #25
0
async def add_new_location(sid: str, location: str):
    pr: PlayerRoom = game_state.get(sid)

    if pr.role != Role.DM:
        logger.warning(f"{pr.player.name} attempted to add a new location")
        return

    new_location = Location.create(room=pr.room,
                                   name=location,
                                   index=pr.room.locations.count())
    new_location.create_floor()

    for psid in game_state.get_sids(player=pr.player,
                                    active_location=pr.active_location):
        sio.leave_room(psid, pr.active_location.get_path(), namespace=GAME_NS)
        sio.enter_room(psid, new_location.get_path(), namespace=GAME_NS)
        await load_location(psid, new_location)
    pr.active_location = new_location
    pr.save()
Example #26
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 #27
0
async def move_shape_order(sid: int, data: Dict[str, Any]):
    pr: PlayerRoom = game_state.get(sid)

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

    if pr.role != Role.DM and not layer.player_editable:
        logger.warning(
            f"{pr.player.name} attempted to move a shape order on a dm layer")
        return

    target = data["index"]
    sign = 1 if target < shape.index else -1
    case = Case(
        None,
        (
            (Shape.index == shape.index, target),
            ((sign * Shape.index) <
             (sign * shape.index), (Shape.index + (sign * 1))),
        ),
        Shape.index,
    )
    Shape.update(index=case).where(Shape.layer == layer).execute()
    if layer.player_visible:
        await sio.emit(
            "Shape.Order.Set",
            data,
            room=pr.active_location.get_path(),
            skip_sid=sid,
            namespace=GAME_NS,
        )
    else:
        for csid in game_state.get_sids(player=pr.room.creator, room=pr.room):
            if csid == sid:
                continue
            await sio.emit("Shape.Order.Set",
                           data["shape"],
                           room=csid,
                           namespace=GAME_NS)
Example #28
0
async def add(sid: str, data: Dict[str, Any]):
    pr: PlayerRoom = game_state.get(sid)

    label = Label.get_or_none(uuid=data)

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

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

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

    for psid in game_state.get_sids(skip_sid=sid, room=pr.room):
        if game_state.get_user(psid) == pr.player or label.visible:
            await sio.emit("Label.Add",
                           label.as_dict(),
                           room=psid,
                           namespace=GAME_NS)
Example #29
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,
                    )