async def remove_label(sid: str, data: ShapeSetStringValue):
    pr: PlayerRoom = game_state.get(sid)

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

    label = ShapeLabel.get_by_id(data["value"])
    label.delete_instance(True)

    await sio.emit(
        "Shape.Options.Label.Remove",
        data,
        skip_sid=sid,
        room=pr.active_location.get_path(),
        namespace=GAME_NS,
    )
async def set_movement_block(sid: str, data: ShapeSetBooleanValue):
    pr: PlayerRoom = game_state.get(sid)

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

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

    await sio.emit(
        "Shape.Options.MovementBlock.Set",
        data,
        skip_sid=sid,
        room=pr.active_location.get_path(),
        namespace=GAME_NS,
    )
async def set_annotation(sid: str, data: ShapeSetStringValue):
    pr: PlayerRoom = game_state.get(sid)

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

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

    for sid in get_owner_sids(pr, shape, skip_sid=sid):
        await sio.emit(
            "Shape.Options.Annotation.Set",
            data,
            room=sid,
            namespace=GAME_NS,
        )
Exemplo n.º 4
0
async def remove_floor(sid, data):
    pr: PlayerRoom = game_state.get(sid)

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

    floor: Floor = Floor.get(location=pr.active_location, name=data)
    floor.delete_instance(recursive=True)

    await sio.emit(
        "Floor.Remove",
        data,
        room=pr.active_location.get_path(),
        skip_sid=sid,
        namespace="/planarally",
    )
Exemplo n.º 5
0
async def set_fill_colour(sid: str, data: ShapeSetStringValue):
    pr: PlayerRoom = game_state.get(sid)

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

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

    await sio.emit(
        "Shape.Options.FillColour.Set",
        data,
        skip_sid=sid,
        room=pr.active_location.get_path(),
        namespace=GAME_NS,
    )
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()

    await sio.emit(
        "Shape.Options.NameVisible.Set",
        data,
        skip_sid=sid,
        room=pr.active_location.get_path(),
        namespace=GAME_NS,
    )
Exemplo n.º 7
0
async def update_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 update owner of 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 update unknown user as owner to shape by {pr.player.name} [{data['user']}]"
        )
        return

    try:
        so = ShapeOwner.get(shape=shape, user=target_user)
    except ShapeOwner.DoesNotExist as exc:
        logger.warning(
            f"Attempt to update unknown shape-owner relation by {pr.player.name}"
        )

    so.shape = shape
    so.user = target_user
    so.edit_access = data["edit_access"]
    so.movement_access = data["movement_access"]
    so.vision_access = data["vision_access"]
    so.save()

    await sio.emit(
        "Shape.Owner.Update",
        data,
        room=pr.active_location.get_path(),
        skip_sid=sid,
        namespace=GAME_NS,
    )
async def update_shape_tracker(sid: str, data: TrackerUpdateData):
    pr: PlayerRoom = game_state.get(sid)

    if data["_type"] == "tracker":
        tracker = Tracker.get_by_id(data["uuid"])
    else:
        tracker = Aura.get_by_id(data["uuid"])

    tracker.value = data["value"]
    tracker.save()

    await sio.emit(
        "Shapes.Trackers.Update",
        data,
        room=pr.active_location.get_path(),
        skip_sid=sid,
        namespace=GAME_NS,
    )
Exemplo n.º 9
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")
Exemplo n.º 10
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)
Exemplo n.º 11
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)
Exemplo n.º 12
0
async def set_floor_background(sid: str, data: FloorBackgroundData):
    pr: PlayerRoom = game_state.get(sid)

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

    floor: Floor = Floor.get(location=pr.active_location, name=data["name"])
    floor.background_color = data.get("background", None)
    floor.save()

    await sio.emit(
        "Floor.Background.Set",
        data,
        room=pr.active_location.get_path(),
        skip_sid=sid,
        namespace=GAME_NS,
    )
Exemplo n.º 13
0
async def create_group(sid: str, group_info: ServerGroup):
    pr: PlayerRoom = game_state.get(sid)

    try:
        Group.get_by_id(group_info["uuid"])
        logger.exception(f"Group with {group_info['uuid']} already exists")
        return
    except Group.DoesNotExist:
        Group.create(**group_info)

    for psid, _ in game_state.get_users(room=pr.room):
        await sio.emit(
            "Group.Create",
            group_info,
            room=psid,
            skip_sid=sid,
            namespace=GAME_NS,
        )
Exemplo n.º 14
0
async def set_floor_type(sid: str, data: FloorTypeData):
    pr: PlayerRoom = game_state.get(sid)

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

    floor: Floor = Floor.get(location=pr.active_location, name=data["name"])
    floor.type_ = data["floorType"]
    floor.save()

    await sio.emit(
        "Floor.Type.Set",
        data,
        room=pr.active_location.get_path(),
        skip_sid=sid,
        namespace=GAME_NS,
    )
Exemplo n.º 15
0
async def rename_floor(sid: str, data: FloorRename):
    pr: PlayerRoom = game_state.get(sid)

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

    floor: Floor = Floor.get(location=pr.active_location, index=data["index"])
    floor.name = data["name"]
    floor.save()

    await sio.emit(
        "Floor.Rename",
        data,
        room=pr.active_location.get_path(),
        skip_sid=sid,
        namespace=GAME_NS,
    )
Exemplo n.º 16
0
async def set_floor_visibility(sid: str, data: FloorVisibleData):
    pr: PlayerRoom = game_state.get(sid)

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

    floor: Floor = Floor.get(location=pr.active_location, name=data["name"])
    floor.player_visible = data["visible"]
    floor.save()

    await sio.emit(
        "Floor.Visible.Set",
        data,
        room=pr.active_location.get_path(),
        namespace=GAME_NS,
    )
Exemplo n.º 17
0
async def update_note(sid: str, data: Dict[str, Any]):
    pr: PlayerRoom = game_state.get(sid)

    note = Note.get_or_none(uuid=data["uuid"])

    if not note:
        logger.warning(
            f"{pr.player.name} tried to update non-existant note with id: '{data['uuid']}'"
        )
        return

    if note.user != pr.player:
        logger.warn(f"{pr.player.name} tried to update note not belonging to him/her.")
    else:
        with db.atomic():
            note.title = data["title"]
            note.text = data["text"]
            note.save()
Exemplo n.º 18
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,
        )
Exemplo n.º 19
0
async def move_aura(sid: str, data: AuraMove):
    pr: PlayerRoom = game_state.get(sid)

    new_shape = get_shape_or_none(pr, data["new_shape"],
                                  "Aura.Options.Tracker.Move")
    if new_shape is None:
        return

    aura = Aura.get_by_id(data["aura"])
    aura.shape = new_shape
    aura.save()

    await sio.emit(
        "Shape.Options.Aura.Move",
        data,
        skip_sid=sid,
        room=pr.active_location.get_path(),
        namespace=GAME_NS,
    )
Exemplo n.º 20
0
async def remove_group(sid: str, group_id: str):
    pr: PlayerRoom = game_state.get(sid)

    for shape in Shape.filter(group_id=group_id).select():
        shape.group = None
        shape.show_badge = False
        shape.save()

    # check if group still has members
    await remove_group_if_empty(group_id)

    for psid, _ in game_state.get_users(room=pr.room):
        await sio.emit(
            "Group.Remove",
            group_id,
            room=psid,
            skip_sid=sid,
            namespace=GAME_NS,
        )
Exemplo n.º 21
0
async def update_circle_size(sid: str, data: CircleSizeData):
    pr: PlayerRoom = game_state.get(sid)

    if not data["temporary"]:
        shape: Union[Circle, CircularToken]
        try:
            shape = CircularToken.get_by_id(data["uuid"])
        except CircularToken.DoesNotExist:
            shape = Circle.get_by_id(data["uuid"])
        shape.radius = data["r"]
        shape.save()

    await sio.emit(
        "Shape.Circle.Size.Update",
        data,
        room=pr.active_location.get_path(),
        skip_sid=sid,
        namespace=GAME_NS,
    )
Exemplo n.º 22
0
async def move_tracker(sid: str, data: TrackerMove):
    pr: PlayerRoom = game_state.get(sid)

    new_shape = get_shape_or_none(pr, data["new_shape"],
                                  "Tracker.Options.Tracker.Move")
    if new_shape is None:
        return

    tracker = Tracker.get_by_id(data["tracker"])
    tracker.shape = new_shape
    tracker.save()

    await sio.emit(
        "Shape.Options.Tracker.Move",
        data,
        skip_sid=sid,
        room=pr.active_location.get_path(),
        namespace=GAME_NS,
    )
Exemplo n.º 23
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()
Exemplo n.º 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
            )
Exemplo n.º 25
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,
                )
Exemplo n.º 26
0
async def update_default_shape_owner(sid: int, data: Dict[str, Any]):
    pr: PlayerRoom = game_state.get(sid)

    try:
        shape: Shape = Shape.get(uuid=data["shape"])
    except Shape.DoesNotExist as exc:
        logger.warning(
            f"Attempt to update owner of 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

    if "edit_access" in data:
        shape.default_edit_access = data["edit_access"]

    if "vision_access" in data:
        shape.default_vision_access = data["vision_access"]

    shape.save()

    await sio.emit(
        "Shape.Owner.Default.Update",
        data,
        room=pr.active_location.get_path(),
        skip_sid=sid,
        namespace="/planarally",
    )

    if shape.default_vision_access or shape.default_edit_access:
        for sid, player in game_state.get_users(
                active_location=pr.active_location):
            await sio.emit(
                "Shape.Set",
                shape.as_dict(player, player.name == pr.room.creator),
                room=sid,
                namespace="/planarally",
            )
Exemplo n.º 27
0
async def set_client(sid: int, data: Dict[str, Any]):
    pr: PlayerRoom = game_state.get(sid)

    with db.atomic():
        for option in [
            ("gridColour", "grid_colour"),
            ("fowColour", "fow_colour"),
            ("rulerColour", "ruler_colour"),
            ("invertAlt", "invert_alt"),
        ]:
            if option[0] in data:
                setattr(pr.player, option[1], data[option[0]])
        pr.player.save()
    if "locationOptions" in data:
        LocationUserOption.update(
            pan_x=data["locationOptions"]["panX"],
            pan_y=data["locationOptions"]["panY"],
            zoom_factor=data["locationOptions"]["zoomFactor"],
        ).where((LocationUserOption.location == pr.active_location)
                & (LocationUserOption.user == pr.player)).execute()
Exemplo n.º 28
0
async def update_initiative_round(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 advance the initiative tracker")
        return

    location_data = InitiativeLocationData.get(location=pr.active_location)
    with db.atomic():
        location_data.round = data
        location_data.save()

    await sio.emit(
        "Initiative.Round.Update",
        data,
        room=pr.active_location.get_path(),
        skip_sid=sid,
        namespace=GAME_NS,
    )
Exemplo n.º 29
0
async def get_location_spawn_info(sid: int, location_id: int):
    pr: PlayerRoom = game_state.get(sid)

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

    location = Location[location_id]

    data = []

    for spawn in json.loads(location.options.spawn_locations):
        shape = Shape[spawn]
        data.append(shape.as_dict(pr.player, True))

    await sio.emit("Location.Spawn.Info",
                   data=data,
                   room=sid,
                   namespace=GAME_NS)
Exemplo n.º 30
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)