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", )
async def move_shape_order(sid: str, data: ShapeOrder): pr: PlayerRoom = game_state.get(sid) if not data["temporary"]: shape = Shape.get(uuid=data["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() await sio.emit( "Shape.Order.Set", data, room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )
async def set_group_leader(sid: str, data: GroupLeaderData): pr: PlayerRoom = game_state.get(sid) leader_shape = Shape.get_by_id(data["leader"]) leader_options = leader_shape.get_options() if "groupId" in leader_options: del leader_options["groupId"] leader_options["groupInfo"] = data["members"] leader_shape.set_options(leader_options) leader_shape.save() for member in data["members"]: shape = Shape.get_by_id(member) options = shape.get_options() options["groupId"] = data["leader"] shape.set_options(options) shape.save() await sio.emit( "Shapes.Group.Leader.Set", data, room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )
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, )
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, )
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)
def insert_shape(shape_id, shape_pt_lat, shape_pt_lon, shape_pt_sequence): """ insert a new shape record :param shape_id: str, shape id :param shape_pt_lat: float, latitude of shape point :param shape_pt_lon: float, longitude of shape point :param shape_pt_sequence: int, sequence of shape point :return: """ d = Shape(shape_id=shape_id, shape_pt_lat=shape_pt_lat, shape_pt_lon=shape_pt_lon, shape_pt_sequence=shape_pt_sequence) d.save()
async def remove_shapes(sid: str, data: TemporaryShapesList): pr: PlayerRoom = game_state.get(sid) if data["temporary"]: # This stuff is not stored so we cannot do any server side validation /shrug for shape in data["uuids"]: game_state.remove_temp(sid, shape) else: # Use the server version of the shapes. try: shapes: List[Shape] = [ s for s in Shape.select().where(Shape.uuid << data["uuids"]) ] except Shape.DoesNotExist: logger.warning( f"Attempt to update unknown shape by {pr.player.name}") return layer = shapes[0].layer group_ids = set() for shape in shapes: if not has_ownership(shape, pr): logger.warning( f"User {pr.player.name} tried to update a shape it does not own." ) return if shape.group: group_ids.add(shape.group) old_index = shape.index shape.delete_instance(True) Shape.update(index=Shape.index - 1).where((Shape.layer == layer) & (Shape.index >= old_index)).execute() for group_id in group_ids: await remove_group_if_empty(group_id) await sio.emit( "Shapes.Remove", data["uuids"], room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )
async def join_group(sid: str, group_join: GroupJoin): pr: PlayerRoom = game_state.get(sid) group_ids = set() for member in group_join["members"]: try: shape = Shape.get_by_id(member["uuid"]) except Shape.DoesNotExist: logger.exception( f"Could not update shape group for unknown shape {member['uuid']}" ) else: if shape.group is not None and shape.group != group_join[ "group_id"]: group_ids.add(shape.group) shape.group = group_join["group_id"] shape.badge = member["badge"] shape.save() # Group joining can be the result of a merge or a split and thus other groups might be empty now for group_id in group_ids: await remove_group_if_empty(group_id) for psid, _ in game_state.get_users(room=pr.room): await sio.emit( "Group.Join", group_join, room=psid, skip_sid=sid, namespace=GAME_NS, )
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")
async def update_shape_options(sid: str, data: OptionUpdateList): pr: PlayerRoom = game_state.get(sid) shapes: List[Tuple[Shape, OptionUpdate]] = [] for sh in data["options"]: shape = Shape.get_or_none(Shape.uuid == sh["uuid"]) if shape is not None and not has_ownership(shape, pr, movement=True): logger.warning( f"User {pr.player.name} attempted to change options for a shape it does not own." ) return shapes.append((shape, sh)) if not data["temporary"]: with db.atomic(): for db_shape, data_shape in shapes: db_shape.options = data_shape["option"] db_shape.save() await sio.emit( "Shapes.Options.Update", data["options"], room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )
async def move_shapes(sid: str, data: ServerShapeLocationMove): pr: PlayerRoom = game_state.get(sid) if pr.role != Role.DM: logger.warning(f"{pr.player.name} attempted to move shape locations") return location = Location.get_by_id(data["target"]["location"]) floor = location.floors.select().where(Floor.name == data["target"]["floor"])[0] x = data["target"]["x"] y = data["target"]["y"] shapes = [Shape.get_by_id(sh) for sh in data["shapes"]] await sio.emit( "Shapes.Remove", [sh.uuid for sh in shapes], room=pr.active_location.get_path(), namespace=GAME_NS, ) for shape in shapes: shape.layer = floor.layers.where(Layer.name == shape.layer.name)[0] shape.center_at(x, y) shape.save() for psid, player in game_state.get_users(active_location=location): await sio.emit( "Shapes.Add", [sh.as_dict(player, game_state.get(psid).role == Role.DM) for sh in shapes], room=psid, namespace=GAME_NS, )
async def update_shape_positions(sid: str, data: PositionUpdateList): pr: PlayerRoom = game_state.get(sid) shapes: List[Tuple[Shape, PositionUpdate]] = [] for sh in data["shapes"]: shape = Shape.get_or_none(Shape.uuid == sh["uuid"]) if shape is not None and not has_ownership(shape, pr, movement=True): logger.warning( f"User {pr.player.name} attempted to move a shape it does not own." ) return shapes.append((shape, sh)) if not data["temporary"]: with db.atomic(): for db_shape, data_shape in shapes: points = data_shape["position"]["points"] db_shape.x = points[0][0] db_shape.y = points[0][1] db_shape.angle = data_shape["position"]["angle"] db_shape.save() if len(points) > 1: # Subshape type_instance = db_shape.subtype type_instance.set_location(points[1:]) await sio.emit( "Shapes.Position.Update", data["shapes"], room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )
async def set_locked(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 locked state 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 locked state of a shape it does not own" ) return shape.is_locked = data["is_locked"] shape.save() await sio.emit( "Shape.Options.Locked.Set", data, skip_sid=sid, room=pr.active_location.get_path(), namespace=GAME_NS, )
async def leave_group(sid: str, client_shapes: List[LeaveGroup]): pr: PlayerRoom = game_state.get(sid) group_ids = set() for client_shape in client_shapes: try: shape = Shape.get_by_id(client_shape["uuid"]) except Shape.DoesNotExist: logger.exception( f"Could not remove shape group for unknown shape {client_shape['uuid']}" ) else: group_ids.add(client_shape["group_id"]) shape.group = None shape.show_badge = False shape.save() for group_id in group_ids: await remove_group_if_empty(group_id) for psid, _ in game_state.get_users(room=pr.room): await sio.emit( "Group.Leave", client_shapes, room=psid, skip_sid=sid, namespace=GAME_NS, )
async def update_initiative_option(sid: str, data: ServerInitiativeOption): pr: PlayerRoom = game_state.get(sid) shape = Shape.get_or_none(uuid=data["shape"]) if not has_ownership(shape, pr): logger.warning( f"{pr.player.name} attempted to change initiative of an asset it does not own" ) return location_data = Initiative.get_or_none(location=pr.active_location) if location_data is None: logger.error( "Initiative updated for location without initiative tracking") return json_data = json.loads(location_data.data) with db.atomic(): for i, initiative_data in enumerate(json_data): if initiative_data["shape"] == data["shape"]: json_data[i][data["option"]] = data["value"] break location_data.data = json.dumps(json_data) location_data.save() await sio.emit( "Initiative.Option.Set", data, skip_sid=sid, room=pr.active_location.get_path(), namespace=GAME_NS, )
async def remove_initiative_effect(sid: str, data: ServerRemoveInitiativeEffectActor): pr: PlayerRoom = game_state.get(sid) if not has_ownership(Shape.get_or_none(uuid=data["shape"]), pr): logger.warning( f"{pr.player.name} attempted to remove an initiative effect") return location_data = Initiative.get(location=pr.active_location) with db.atomic(): json_data = json.loads(location_data.data) for initiative in json_data: if initiative["shape"] == data["shape"]: initiative["effects"].pop(data["index"]) location_data.data = json.dumps(json_data) location_data.save() await sio.emit( "Initiative.Effect.Remove", data, room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )
async def remove_initiative(sid: str, data: str): pr: PlayerRoom = game_state.get(sid) shape = Shape.get_or_none(uuid=data) if shape is not None and not has_ownership(shape, pr): logger.warning( f"{pr.player.name} attempted to remove initiative of an asset it does not own" ) return with db.atomic(): location_data = Initiative.get(location=pr.active_location) json_data = json.loads(location_data.data) location_data.data = json.dumps([ initiative for initiative in json_data if initiative["shape"] != data ]) location_data.save() await sio.emit( "Initiative.Remove", data, room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )
async def update_initiative_round(sid: str, data: int): pr: PlayerRoom = game_state.get(sid) location_data = Initiative.get(location=pr.active_location) if pr.role != Role.DM: json_data = json.loads(location_data.data) if not has_ownership( Shape.get_or_none(uuid=json_data[location_data.turn]["shape"]), pr): logger.warning( f"{pr.player.name} attempted to advance the initiative tracker" ) return 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, )
async def get_location_spawn_info(sid: str, 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 data = [] try: location = Location.get_by_id(location_id) if location.options is not None: for spawn in json.loads(location.options.spawn_locations): try: shape = Shape.get_by_id(spawn) except Shape.DoesNotExist: pass else: data.append(shape.as_dict(pr.player, True)) except: logger.exception("Could not load spawn locations") await sio.emit("Location.Spawn.Info", data=data, room=sid, namespace=GAME_NS)
async def set_initiative_value(sid: str, data: ServerSetInitiativeValue): pr: PlayerRoom = game_state.get(sid) shape = Shape.get_or_none(uuid=data) if shape is not None and not has_ownership(shape, pr): logger.warning( f"{pr.player.name} attempted to remove initiative of an asset it does not own" ) return with db.atomic(): location_data = Initiative.get(location=pr.active_location) json_data = json.loads(location_data.data) for initiative in json_data: if initiative["shape"] == data["shape"]: initiative["initiative"] = data["value"] break json_data = sort_initiative(json_data, location_data.sort) location_data.data = json.dumps(json_data) location_data.save() await sio.emit( "Initiative.Set", location_data.as_dict(), room=pr.active_location.get_path(), namespace=GAME_NS, )
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)
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")
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")
async def remove_group_if_empty(group_id: str): try: group = Group.get_by_id(group_id) except Group.DoesNotExist: return if Shape.filter(group=group_id).count() == 0: group.delete_instance(True)
def parse(self): with open(self.filename, 'rb') as file: reader = UnicodeReader(file) columns = reader.next() shape_id, lat, lon, seq = reader.next() shape = Shape(shape_id) points = [(lat, lon)] for line in reader: shape_id, lat, lon, seq = line if shape_id != shape.id: shape.geometry = \ WKTSpatialElement(pointsToLineString(points)) yield shape shape = Shape(shape_id) points = [(lat, lon)] else: points.append((lat, lon))
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, )
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)
def get_shape_or_none(pr: PlayerRoom, shape_id: str, action: str) -> Union[Shape, None]: try: shape: Shape = Shape.get(uuid=shape_id) except Shape.DoesNotExist as exc: logger.warning( f"Attempt by {pr.player.name} on unknown shape. {{method: {action}, shape id: {shape_id}}}" ) raise exc if not has_ownership(shape, pr): logger.warning( f"Attempt by {pr.player.name} on shape they do not own. {{method: {action}, shape id: {shape_id}}}" ) return None return shape
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}" ) return 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 add_group_member(sid: str, data: GroupMemberAddData): pr: PlayerRoom = game_state.get(sid) leader_shape = Shape.get_by_id(data["leader"]) leader_options = leader_shape.get_options() leader_options["groupInfo"].append(data["member"]) leader_shape.set_options(leader_options) leader_shape.save() await sio.emit( "Shapes.Group.Member.Add", data, room=pr.active_location.get_path(), skip_sid=sid, namespace=GAME_NS, )