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 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 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)
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 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")
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", )
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", )
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")
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, )
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", )
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)
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)