Beispiel #1
0
 def _send_tracker_to_client(self, init=False):
     msg_empty = True
     msg = Area_pb2.AchievementTrackerUpdate()
     for achievement in self._completed_milestones:
         if not self.milestone_sent(achievement):
             self._sent_milestones.add(achievement)
             msg.achievements_completed.append(achievement.guid64)
             if msg_empty:
                 msg_empty = False
     for objective in self._completed_objectives:
         if not self.objective_sent(objective):
             self._sent_objectives.add(objective)
             msg.objectives_completed.append(objective.guid64)
             if msg_empty:
                 msg_empty = False
     if not msg_empty:
         msg.account_id = self._account_id
         msg.init_message = init
         cheat_service = services.get_cheat_service()
         msg.cheats_used = cheat_service.cheats_ever_enabled
         distributor = Distributor.instance()
         owner = self.owner_sim_info
         if owner is None:
             distributor.add_op_with_no_owner(GenericProtocolBufferOp(Operation.ACCT_ACHIEVEMENT_TRACKER_UPDATE, msg))
         else:
             distributor.add_op(owner, GenericProtocolBufferOp(Operation.ACCT_ACHIEVEMENT_TRACKER_UPDATE, msg))
Beispiel #2
0
 def _send_objectives_update_to_client(self):
     msg = Area_pb2.AcctGoalsStatusUpdate()
     if self._update_objectives_msg_for_client(msg):
         msg.account_id = self._account_id
         distributor = Distributor.instance()
         owner = self.owner_sim_info
         if owner is None:
             distributor.add_op_with_no_owner(GenericProtocolBufferOp(Operation.ACCT_GOALS_STATUS_UPDATE, msg))
         else:
             distributor.add_op(owner, GenericProtocolBufferOp(Operation.ACCT_ACHIEVEMENT_TRACKER_UPDATE, msg))
Beispiel #3
0
 def send_daily_profit_and_cost_update(self):
     if self.is_owner_household_active:
         profit_msg = Business_pb2.BusinessProfitUpdate()
         profit_msg.zone_id = self.business_zone_id
         profit_msg.net_profit = self.get_daily_net_profit(include_employee_wages=False)
         op = GenericProtocolBufferOp(DistributorOps_pb2.Operation.BUSINESS_PROFIT_UPDATE, profit_msg)
         Distributor.instance().add_op_with_no_owner(op)
         cost_msg = Business_pb2.BusinessDailyCostsUpdate()
         cost_msg.zone_id = self.business_zone_id
         cost_msg.daily_outgoing_costs = int(self.get_daily_outgoing_costs())
         op = GenericProtocolBufferOp(DistributorOps_pb2.Operation.BUSINESS_DAILY_OUTGOING_COSTS_UPDATE, cost_msg)
         Distributor.instance().add_op_with_no_owner(op)
Beispiel #4
0
 def _send_destroy_message_to_client(self):
     msg_a = commodity_protocol.RelationshipDelete()
     msg_a.actor_sim_id = self._sim_id_a
     msg_a.target_id = self._sim_id_b
     op_a = GenericProtocolBufferOp(
         DistributorOps_pb2.Operation.SIM_RELATIONSHIP_DELETE, msg_a)
     distributor = Distributor.instance()
     distributor.add_op(self.find_sim_info_a(), op_a)
     if not self._is_object_rel:
         msg_b = commodity_protocol.RelationshipDelete()
         msg_b.actor_sim_id = self._sim_id_b
         msg_b.target_id = self._sim_id_a
         op_b = GenericProtocolBufferOp(
             DistributorOps_pb2.Operation.SIM_RELATIONSHIP_DELETE, msg_b)
         distributor.add_op(self.find_sim_info_b(), op_b)
Beispiel #5
0
 def show_festival_info(cls):
     if cls.festival_dynamic_sign_info is None:
         return
     ui_info = cls.festival_dynamic_sign_info
     festival_info = UI_pb2.DynamicSignView()
     festival_info.drama_node_guid = cls.guid64
     festival_info.name = ui_info.festival_name
     lot_id = cls.get_travel_lot_id()
     persistence_service = services.get_persistence_service()
     zone_id = persistence_service.resolve_lot_id_into_zone_id(lot_id, ignore_neighborhood_id=True)
     zone_protobuff = persistence_service.get_zone_proto_buff(zone_id)
     if zone_protobuff is not None:
         festival_info.venue = LocalizationHelperTuning.get_raw_text(zone_protobuff.name)
     festival_info.time = ui_info.festival_time
     festival_info.image = sims4.resources.get_protobuff_for_key(ui_info.display_image)
     festival_info.background_image = sims4.resources.get_protobuff_for_key(ui_info.background_image)
     festival_info.action_label = ui_info.travel_to_festival_text
     running_nodes = services.drama_scheduler_service().get_running_nodes_by_class(cls)
     active_sim_info = services.active_sim_info()
     if all(active_node.is_during_pre_festival() for active_node in running_nodes):
         festival_info.disabled_tooltip = ui_info.festival_not_started_tooltip
     elif any(active_node.is_on_festival_street() for active_node in running_nodes):
         festival_info.disabled_tooltip = ui_info.on_street_tooltip
     elif active_sim_info.is_in_travel_group():
         festival_info.disabled_tooltip = ui_info.on_vacation_tooltip
     for activity in ui_info.activity_info:
         with ProtocolBufferRollback(festival_info.activities) as activity_msg:
             activity_msg.name = activity.activity_name
             activity_msg.description = activity.activity_description
             activity_msg.icon = create_icon_info_msg(IconInfoData(activity.icon))
     distributor = Distributor.instance()
     distributor.add_op(active_sim_info, GenericProtocolBufferOp(Operation.DYNAMIC_SIGN_VIEW, festival_info))
Beispiel #6
0
 def _send_tracker_to_client(self, init=False):
     owner = self.owner_sim_info
     if owner is None or owner.is_npc or owner.manager is None:
         return
     msg_empty = True
     msg = Sims_pb2.AspirationTrackerUpdate()
     for aspiration in self._completed_milestones:
         if not self.milestone_sent(aspiration):
             self._sent_milestones.add(aspiration)
             msg.aspirations_completed.append(aspiration.guid64)
             msg_empty = False
     for objective in self._completed_objectives:
         if not self.objective_sent(objective):
             self._sent_objectives.add(objective)
             msg.objectives_completed.append(objective.guid64)
             msg_empty = False
     for objective in self._reset_objectives:
         if not self.objective_sent(objective):
             self._sent_objectives.add(objective)
             msg.objectives_reset.append(objective.guid64)
             msg_empty = False
     for unlocked_hidden_aspiration_track in self._unlocked_hidden_aspiration_tracks:
         if not self.unlocked_hidden_aspiration_track_sent(
                 unlocked_hidden_aspiration_track):
             msg.unlocked_hidden_aspiration_tracks.append(
                 unlocked_hidden_aspiration_track.guid64)
             msg_empty = False
     if not msg_empty:
         msg.sim_id = owner.id
         msg.init_message = init
         distributor = Distributor.instance()
         distributor.add_op(
             owner,
             GenericProtocolBufferOp(
                 Operation.SIM_ASPIRATION_TRACKER_UPDATE, msg))
Beispiel #7
0
 def send_selectable_sims_update(self):
     msg = Sims_pb2.UpdateSelectableSims()
     for sim_info in self._selectable_sims:
         with ProtocolBufferRollback(msg.sims) as new_sim:
             new_sim.id = sim_info.sim_id
             if sim_info.career_tracker is None:
                 logger.error(
                     'CareerTracker is None for selectable Sim {}'.format(
                         sim_info))
             else:
                 career = sim_info.career_tracker.get_currently_at_work_career(
                 )
                 new_sim.at_work = career is not None and not career.is_at_active_event
             new_sim.is_selectable = sim_info.is_enabled_in_skewer
             (selector_visual_type,
              career_category) = self._get_selector_visual_type(sim_info)
             new_sim.selector_visual_type = selector_visual_type
             if career_category is not None:
                 new_sim.career_category = career_category
             new_sim.can_care_for_toddler_at_home = sim_info.can_care_for_toddler_at_home
             if not sim_info.is_instanced(
                     allow_hidden_flags=ALL_HIDDEN_REASONS):
                 new_sim.instance_info.zone_id = sim_info.zone_id
                 new_sim.instance_info.world_id = sim_info.world_id
                 new_sim.firstname = sim_info.first_name
                 new_sim.lastname = sim_info.last_name
                 zone_data_proto = services.get_persistence_service(
                 ).get_zone_proto_buff(sim_info.zone_id)
                 if zone_data_proto is not None:
                     new_sim.instance_info.zone_name = zone_data_proto.name
     distributor = Distributor.instance()
     distributor.add_op_with_no_owner(
         GenericProtocolBufferOp(Operation.SELECTABLE_SIMS_UPDATE, msg))
Beispiel #8
0
 def _on_remove_sim_from_situation(self, sim):
     if not services.current_zone().is_zone_running:
         super()._on_remove_sim_from_situation(sim)
         return
     sim_job = self.get_current_job_for_sim(sim)
     services.get_zone_situation_manager().add_sim_to_auto_fill_blacklist(
         sim.id, sim_job=sim_job)
     (pet_sim_info,
      pet_owner_sim_info) = self._get_pet_and_owner_sim_infos()
     pet_sim_info.remove_linked_sim(pet_owner_sim_info.sim_id)
     pet_owner_sim_info.remove_linked_sim(pet_sim_info.sim_id)
     pet_owner = self.get_pet_owner()
     is_pet_owner = False if pet_owner is None else sim is pet_owner
     super()._on_remove_sim_from_situation(sim)
     business_manager = services.business_service(
     ).get_business_manager_for_zone()
     if business_manager is not None and is_pet_owner:
         business_manager.remove_customer(
             sim, review_business=self._should_leave_review)
         customer_msg = Business_pb2.BusinessCustomerUpdate()
         customer_msg.sim_id = pet_owner_sim_info.sim_id
         op = GenericProtocolBufferOp(
             DistributorOps_pb2.Operation.BUSINESS_CUSTOMER_REMOVE,
             customer_msg)
         Distributor.instance().add_op_with_no_owner(op)
 def on_response(dialog):
     if not dialog.accepted:
         self.cancel_user(
             cancel_reason_msg=
             'Move-In. Player canceled, or move in together dialog timed out from client.'
         )
         return
     actor = self.get_participant(ParticipantType.Actor)
     src_household_id = actor.sim_info.household.id
     target = self.target
     tgt_household_id = target.sim_info.household.id
     client_manager = services.client_manager()
     if client_manager is not None:
         client = client_manager.get_first_client()
         if client is not None:
             active_sim_id = client.active_sim.id
     if src_household_id is not None and tgt_household_id is not None and active_sim_id is not None:
         transfer_info = InteractionOps_pb2.SimTransferRequest()
         transfer_info.source_household_id = src_household_id
         transfer_info.target_household_id = tgt_household_id
         transfer_info.active_sim_id = active_sim_id
         system_distributor = distributor.system.Distributor.instance()
         generic_pb_op = GenericProtocolBufferOp(
             DistributorOps_pb2.Operation.SIM_TRANSFER_REQUEST,
             transfer_info)
         system_distributor.add_op_with_no_owner(generic_pb_op)
Beispiel #10
0
 def _send_daily_items_sold_update(self):
     if self.is_active_household_and_zone():
         items_sold_msg = Business_pb2.BusinessDailyItemsSoldUpdate()
         items_sold_msg.zone_id = self.business_zone_id
         items_sold_msg.daily_items_sold = self.daily_items_sold
         op = GenericProtocolBufferOp(DistributorOps_pb2.Operation.BUSINESS_DAILY_ITEMS_SOLD_UPDATE, items_sold_msg)
         Distributor.instance().add_op_with_no_owner(op)
Beispiel #11
0
def send_reject_response(client, sim, context_handle, cancel_reason):
    reject_msg = protocols.ServerResponseFailed()
    reject_msg.handle = context_handle
    reject_msg.reason = cancel_reason
    distributor = Distributor.instance()
    distributor.add_op_with_no_owner(GenericProtocolBufferOp(Operation.SIM_SERVER_RESPONSE_FAILED, reject_msg))
    logger.debug('    sending reject msg')
Beispiel #12
0
 def _run_gen(self, timeline):
     stereo_component = self.target.get_component(STEREO_COMPONENT)
     if stereo_component is None:
         logger.error(
             'object {} being used as stereo but has no stereo component',
             self.target,
             owner='thomaskenney')
         return False
         yield
     play_audio_primative = self.target.get_component_managed_state_distributable(
         'audio_state', stereo_component.channel_state)
     if play_audio_primative is not None:
         msg = Audio_pb2.SoundSkipToNext()
         msg.object_id = self.target.id
         if self.target.inventoryitem_component is not None:
             forward_to_owner_list = self.target.inventoryitem_component.forward_client_state_change_to_inventory_owner
             if forward_to_owner_list:
                 if StateChange.AUDIO_STATE in forward_to_owner_list:
                     if self.target.inventoryitem_component.inventory_owner is not None:
                         msg.object_id = self.target.inventoryitem_component.inventory_owner.id
         msg.channel = play_audio_primative.channel
         distributor = Distributor.instance()
         distributor.add_op_with_no_owner(
             GenericProtocolBufferOp(
                 Operation.OBJECT_AUDIO_PLAYLIST_SKIP_TO_NEXT, msg))
     return True
     yield
Beispiel #13
0
 def _send_skill_delete_message(self):
     if self.tracker.owner.is_npc:
         return
     skill_msg = Commodities_pb2.SkillDelete()
     skill_msg.skill_id = self.guid64
     op = GenericProtocolBufferOp(Operation.SIM_SKILL_DELETE, skill_msg)
     Distributor.instance().add_op(self.tracker.owner, op)
Beispiel #14
0
 def display_scholarship_info(self, subject):
     if self.SCHOLARSHIP_INFORMATION_SIGN.display_image is None or self.SCHOLARSHIP_INFORMATION_SIGN.background_image is None:
         logger.error(
             'Attempting to show scholarship sign to ({}) when content is None.',
             subject)
         return
     sign_info = UI_pb2.DynamicSignView()
     sign_info.name = self.SCHOLARSHIP_INFORMATION_SIGN.title
     sign_info.image = sims4.resources.get_protobuff_for_key(
         self.SCHOLARSHIP_INFORMATION_SIGN.display_image)
     sign_info.background_image = sims4.resources.get_protobuff_for_key(
         self.SCHOLARSHIP_INFORMATION_SIGN.background_image)
     for sub_info in self.SCHOLARSHIP_INFORMATION_SIGN.sub_infos:
         with ProtocolBufferRollback(sign_info.activities) as activity_msg:
             if sub_info.icon is None:
                 logger.error(
                     'Attempting to show scholarship sign to ({}) when sub_info icon is None.',
                     subject)
                 continue
             activity_msg.name = sub_info.name
             activity_msg.description = sub_info.desc
             activity_msg.icon = create_icon_info_msg(
                 IconInfoData(sub_info.icon))
     distributor = Distributor.instance()
     distributor.add_op(
         subject.sim_info,
         GenericProtocolBufferOp(Operation.DYNAMIC_SIGN_VIEW, sign_info))
     services.get_event_manager().process_event(
         TestEvent.ScholarshipInfoSignShown, sim_info=subject)
Beispiel #15
0
 def _distribute_business_open_status(self, is_open=True, open_time=0):
     open_msg = Business_pb2.BusinessIsOpenUpdate()
     open_msg.is_open = is_open
     open_msg.time_opened = open_time
     open_msg.zone_id = self.business_zone_id
     op = GenericProtocolBufferOp(DistributorOps_pb2.Operation.BUSINESS_OPEN_UPDATE, open_msg)
     Distributor.instance().add_op_with_no_owner(op)
Beispiel #16
0
 def perform(self, subject, target, resolver):
     if subject is None:
         logger.error(
             'Trying to perform UniversityDynamicSignView op but subject is None. Resolver {}.',
             resolver)
         return
     if not subject.is_sim:
         logger.error(
             'Trying to perform UniversityDynamicSignView op but subject {} is not Sim. Resolver {}.',
             subject, resolver)
         return
     sign_info = UI_pb2.DynamicSignView()
     sign_info.name = self.title
     sign_info.image = sims4.resources.get_protobuff_for_key(
         self.display_image)
     sign_info.background_image = sims4.resources.get_protobuff_for_key(
         self.background_image)
     for sub_info in self.sub_infos:
         with ProtocolBufferRollback(
                 sign_info.activities) as activity_msg:
             activity_msg.name = sub_info.name
             activity_msg.description = sub_info.desc.get_string(
                 subject.sim_info)
             activity_msg.icon = create_icon_info_msg(
                 IconInfoData(sub_info.icon))
     distributor = Distributor.instance()
     distributor.add_op(
         subject.sim_info,
         GenericProtocolBufferOp(Operation.DYNAMIC_SIGN_VIEW,
                                 sign_info))
Beispiel #17
0
 def send_business_funds_update(self):
     if self.is_owner_household_active:
         funds_msg = Business_pb2.BusinessFundsUpdate()
         funds_msg.available_funds = self.funds.money
         funds_msg.zone_id = self.business_zone_id
         op = GenericProtocolBufferOp(DistributorOps_pb2.Operation.BUSINESS_FUNDS_UPDATE, funds_msg)
         Distributor.instance().add_op_with_no_owner(op)
 def _send_tracker_to_client(self, init=False):
     owner = self.owner_sim_info
     if owner is None or owner.is_npc or owner.manager is None:
         return
     msg_empty = True
     msg = Sims_pb2.AspirationTrackerUpdate()
     for guid in self._completed_milestones:
         while not self.milestone_sent(guid):
             self._sent_milestones.add(guid)
             msg.aspirations_completed.append(guid)
             if msg_empty:
                 msg_empty = False
     for guid in self._completed_objectives:
         while not self.objective_sent(guid):
             self._sent_objectives.add(guid)
             msg.objectives_completed.append(guid)
             if msg_empty:
                 msg_empty = False
     if not msg_empty:
         msg.sim_id = owner.id
         msg.init_message = init
         distributor = Distributor.instance()
         distributor.add_op(
             owner,
             GenericProtocolBufferOp(
                 Operation.SIM_ASPIRATION_TRACKER_UPDATE, msg))
Beispiel #19
0
 def _send_destroy_message_to_client(self):
     msg = commodity_protocol.RelationshipDelete()
     msg.actor_sim_id = self._sim_id
     msg.target_id = self._target_sim_id
     op = GenericProtocolBufferOp(
         DistributorOps_pb2.Operation.SIM_RELATIONSHIP_DELETE, msg)
     distributor = Distributor.instance()
     distributor.add_op(self.find_sim_info(), op)
Beispiel #20
0
 def distribute_inventory_stack_update_message(self, obj):
     if obj.id not in self._objects:
         return
     msg = self._get_inventory_update_message(
         UI_pb2.InventoryItemUpdate.TYPE_SET_STACK_OPTION, obj)
     if msg is not None:
         op = GenericProtocolBufferOp(Operation.INVENTORY_ITEM_UPDATE, msg)
         Distributor.instance().add_op_with_no_owner(op)
Beispiel #21
0
 def send_buff_update_msg(self, buff, equipped, change_rate=None, immediate=False):
     if not buff.visible:
         return
     if self.owner.valid_for_distribution and self.owner.is_sim and self.owner.is_selectable:
         buff_msg = self._create_buff_update_msg(buff, equipped, change_rate=change_rate)
         if gsi_handlers.buff_handlers.sim_buff_log_archiver.enabled:
             gsi_handlers.buff_handlers.archive_buff_message(buff_msg, equipped, change_rate)
         Distributor.instance().add_op(self.owner, GenericProtocolBufferOp(Operation.SIM_BUFF_UPDATE, buff_msg))
Beispiel #22
0
 def distribute_owned_inventory_update_message(self, obj, owner):
     if obj.id not in self._objects:
         return False
     msg = self._get_inventory_update_message(
         UI_pb2.InventoryItemUpdate.TYPE_UPDATE, obj)
     if msg is not None:
         op = GenericProtocolBufferOp(Operation.INVENTORY_ITEM_UPDATE, msg)
         Distributor.instance().add_op(owner, op)
 def _send_advertisement_update_message(self):
     msg = Business_pb2.BusinessAdvertisementUpdate()
     msg.zone_id = self._business_manager.business_zone_id
     msg.advertisement_chosen = self._advertising_type
     op = GenericProtocolBufferOp(
         DistributorOps_pb2.Operation.BUSINESS_ADVERTISEMENT_DATA_UPDATE,
         msg)
     Distributor.instance().add_op_with_no_owner(op)
Beispiel #24
0
 def send_data_to_client(self):
     zone = services.get_zone(self._zone_id, allow_uninstantiated_zones=True)
     if zone is None:
         logger.error('Trying to send the business data to client but the business manager {} has an invalid zone id.', self)
         return
     business_data_msg = Business_pb2.SetBusinessData()
     self.construct_business_message(business_data_msg)
     business_data_op = GenericProtocolBufferOp(DistributorOps_pb2.Operation.SET_BUSINESS_DATA, business_data_msg)
     Distributor.instance().add_op_with_no_owner(business_data_op)
Beispiel #25
0
 def distribute_dialog(self, dialog_type, dialog_msg, **kwargs):
     distributor = Distributor.instance()
     notification_op = GenericProtocolBufferOp(
         Operation.UI_NOTIFICATION_SHOW, dialog_msg)
     owner = self.owner
     if owner is not None and owner.valid_for_distribution:
         distributor.add_op(owner, notification_op)
     else:
         distributor.add_op_with_no_owner(notification_op)
Beispiel #26
0
 def _run_gen(self, timeline):
     play_audio_primative = self.target.get_component_managed_state_distributable('audio_state', self.affordance.audio_state_type)
     if play_audio_primative is not None:
         msg = Audio_pb2.SoundSkipToNext()
         msg.object_id = self.target.id
         msg.channel = play_audio_primative.channel
         distributor = Distributor.instance()
         distributor.add_op_with_no_owner(GenericProtocolBufferOp(Operation.OBJECT_AUDIO_PLAYLIST_SKIP_TO_NEXT, msg))
     return True
     yield None
Beispiel #27
0
 def open_ui_panel(self, obj):
     if not self._allow_ui:
         return False
     msg = UI_pb2.OpenInventory()
     msg.object_id = obj.id
     msg.inventory_id = self._get_inventory_id()
     msg.inventory_type = self._get_inventory_ui_type()
     op = GenericProtocolBufferOp(Operation.OPEN_INVENTORY, msg)
     Distributor.instance().add_op_with_no_owner(op)
     return True
Beispiel #28
0
 def get_item_update_ops_gen(self):
     stack_options_set = set()
     for obj in self._objects.values():
         message = self._get_inventory_update_message(
             UI_pb2.InventoryItemUpdate.TYPE_ADD,
             obj,
             allow_while_zone_not_running=True)
         if message is None:
             continue
         yield (obj,
                GenericProtocolBufferOp(Operation.INVENTORY_ITEM_UPDATE,
                                        message))
         if not obj.inventoryitem_component.has_stack_option:
             obj_owner = obj.inventoryitem_component.get_inventory().owner
             if obj_owner.is_sim:
                 if obj_owner.sim_info.favorites_tracker is None:
                     continue
                 stack_id = obj.inventoryitem_component.get_stack_id()
                 if stack_id in stack_options_set:
                     continue
                 option_msg = self._get_inventory_update_message(
                     UI_pb2.InventoryItemUpdate.TYPE_SET_STACK_OPTION,
                     obj,
                     allow_while_zone_not_running=True)
                 if option_msg is not None:
                     stack_options_set.add(stack_id)
                     yield (obj,
                            GenericProtocolBufferOp(
                                Operation.INVENTORY_ITEM_UPDATE,
                                option_msg))
         else:
             stack_id = obj.inventoryitem_component.get_stack_id()
             if stack_id in stack_options_set:
                 continue
             option_msg = self._get_inventory_update_message(
                 UI_pb2.InventoryItemUpdate.TYPE_SET_STACK_OPTION,
                 obj,
                 allow_while_zone_not_running=True)
             if option_msg is not None:
                 stack_options_set.add(stack_id)
                 yield (obj,
                        GenericProtocolBufferOp(
                            Operation.INVENTORY_ITEM_UPDATE, option_msg))
Beispiel #29
0
 def _distribute_inventory_update_message(self,
                                          update_type,
                                          obj,
                                          obj_id=None):
     msg = self._get_inventory_update_message(update_type,
                                              obj,
                                              obj_id=obj_id)
     if msg is not None:
         op = GenericProtocolBufferOp(Operation.INVENTORY_ITEM_UPDATE, msg)
         Distributor.instance().add_op_with_no_owner(op)
 def _send_calendary_entry(self, drama_node, update_type):
     if drama_node.ui_display_type == DramaNodeUiDisplayType.ALERTS_ONLY:
         return
     calendar_entry = drama_node.create_calendar_entry()
     calendar_msg = UI_pb2.CalendarUpdate()
     calendar_msg.updated_entry = calendar_entry
     calendar_msg.update_type = update_type
     op = GenericProtocolBufferOp(Operation.MSG_CALENDAR_UPDATE,
                                  calendar_msg)
     Distributor.instance().add_op_with_no_owner(op)