void wamp_dealer::process_call_message(const wamp_session_id& session_id, wamp_call_message* call_message) { auto session_itr = m_sessions.find(session_id); if (session_itr == m_sessions.end()) { throw std::logic_error("dealer session does not exist"); } BONEFISH_TRACE("%1%, %2%", *session_itr->second % *call_message); // If the session placing the call does not support the caller role // than do not allow the call to be processed and send an error. if (!session_itr->second->get_role(wamp_role_type::CALLER)) { send_error(session_itr->second->get_transport(), call_message->get_type(), call_message->get_request_id(), "wamp.error.role_violation"); return; } const auto procedure = call_message->get_procedure(); if (!is_valid_uri(procedure)) { send_error(session_itr->second->get_transport(), call_message->get_type(), call_message->get_request_id(), "wamp.error.invalid_uri"); return; } auto procedure_registrations_itr = m_procedure_registrations.find(procedure); if (procedure_registrations_itr == m_procedure_registrations.end()) { send_error(session_itr->second->get_transport(), call_message->get_type(), call_message->get_request_id(), "wamp.error.no_such_procedure"); return; } std::shared_ptr<wamp_session> session = procedure_registrations_itr->second->get_session(); const wamp_request_id request_id = m_request_id_generator.generate(); const wamp_registration_id& registration_id = procedure_registrations_itr->second->get_registration_id(); wamp_call_options call_options; call_options.unmarshal(call_message->get_options()); // You can't rely on simply assigning the call options to the invocation // details. Some call options may only be applicable to the dealer and // not the callee. Likewise, some invocation details may be in addition // to whatever is provided in the call options. As a result, we only copy // specific options over to the invocation details. wamp_invocation_details invocation_details; if (call_options.get_option_or("receive_progress", false)) { invocation_details.set_detail("receive_progress", true); } std::unique_ptr<wamp_invocation_message> invocation_message( new wamp_invocation_message(call_message->release_zone())); invocation_message->set_request_id(request_id); invocation_message->set_registration_id(registration_id); invocation_message->set_details(invocation_details.marshal(invocation_message->get_zone())); invocation_message->set_arguments(call_message->get_arguments()); invocation_message->set_arguments_kw(call_message->get_arguments_kw()); BONEFISH_TRACE("%1%, %2%", *session_itr->second % *invocation_message); if (!session->get_transport()->send_message(std::move(*invocation_message))) { BONEFISH_TRACE("sending invocation message to callee failed: network failure"); send_error(session_itr->second->get_transport(), call_message->get_type(), call_message->get_request_id(), "wamp.error.network_failure"); return; } unsigned timeout_ms = call_options.get_option_or<unsigned>("timeout", 0); // We only setup the invocation state after sending the message is successful. // This saves us from having to cleanup any state if the send fails. std::unique_ptr<wamp_dealer_invocation> dealer_invocation( new wamp_dealer_invocation(m_io_service)); dealer_invocation->set_session(session_itr->second); dealer_invocation->set_request_id(call_message->get_request_id()); dealer_invocation->set_timeout( std::bind(&wamp_dealer::invocation_timeout_handler, this, request_id, std::placeholders::_1), timeout_ms); m_pending_invocations.insert(std::make_pair(request_id, std::move(dealer_invocation))); m_pending_callee_invocations[session->get_session_id()].insert(request_id); m_pending_caller_invocations[session_id].insert(request_id); }
void teleds(int nux, int nuy, boolean allow_drag) { boolean ball_active = (Punished && uball->where != OBJ_FREE), ball_still_in_range = FALSE; /* If they have to move the ball, then drag if allow_drag is true; otherwise they are teleporting, so unplacebc(). If they don't have to move the ball, then always "drag" whether or not allow_drag is true, because we are calling that function, not to drag, but to move the chain. *However* there are some dumb special cases: 0 0 _X move east -----> X_ @ @ These are permissible if teleporting, but not if dragging. As a result, drag_ball() needs to know about allow_drag and might end up dragging the ball anyway. Also, drag_ball() might find that dragging the ball is completely impossible (ball in range but there's rock in the way), in which case it teleports the ball on its own. */ if (ball_active) { if (!carried(uball) && distmin(nux, nuy, uball->ox, uball->oy) <= 2) ball_still_in_range = TRUE; /* don't have to move the ball */ else { /* have to move the ball */ if (!allow_drag || distmin(u.ux, u.uy, nux, nuy) > 1) { /* we should not have dist > 1 and allow_drag at the same time, but just in case, we must then revert to teleport. */ allow_drag = FALSE; unplacebc(); } } } u.utrap = 0; u.ustuck = 0; u.ux0 = u.ux; u.uy0 = u.uy; if (hides_under(youmonst.data)) u.uundetected = OBJ_AT(nux, nuy); else if (youmonst.data->mlet == S_EEL) u.uundetected = is_pool(level, nux, nuy); else { u.uundetected = 0; /* mimics stop being unnoticed */ if (youmonst.data->mlet == S_MIMIC) youmonst.m_ap_type = M_AP_NOTHING; } if (Engulfed) { u.uswldtim = Engulfed = 0; if (Punished && !ball_active) { /* ensure ball placement, like unstuck */ ball_active = TRUE; allow_drag = FALSE; } doredraw(); } if (ball_active) { if (ball_still_in_range || allow_drag) { int bc_control; xchar ballx, bally, chainx, chainy; boolean cause_delay; if (drag_ball (nux, nuy, &bc_control, &ballx, &bally, &chainx, &chainy, &cause_delay, allow_drag)) move_bc(0, bc_control, ballx, bally, chainx, chainy); } } /* must set u.ux, u.uy after drag_ball(), which may need to know the old position if allow_drag is true... */ u.ux = nux; u.uy = nuy; fill_pit(level, u.ux0, u.uy0); if (ball_active) { if (!ball_still_in_range && !allow_drag) placebc(); } initrack(); /* teleports mess up tracking monsters without this */ update_player_regions(level); /* Move your steed, too */ if (u.usteed) { u.usteed->mx = nux; u.usteed->my = nuy; } /* * Make sure the hero disappears from the old location. This will * not happen if she is teleported within sight of her previous * location. Force a full vision recalculation because the hero * is now in a new location. */ newsym(u.ux0, u.uy0); see_monsters(FALSE); turnstate.vision_full_recalc = TRUE; action_interrupted(); vision_recalc(0); /* vision before effects */ spoteffects(TRUE); invocation_message(); }
void wamp_dealer::process_call_message(const wamp_session_id& session_id, wamp_call_message* call_message) { auto session_itr = m_sessions.find(session_id); if (session_itr == m_sessions.end()) { throw std::logic_error("dealer session does not exist"); } BONEFISH_TRACE("%1%, %2%", *session_itr->second % *call_message); // If the session placing the call does not support the caller role // than do not allow the call to be processed and send an error. if (!session_itr->second->get_role(wamp_role_type::CALLER)) { send_error(session_itr->second->get_transport(), call_message->get_type(), call_message->get_request_id(), "wamp.error.role_violation"); return; } const auto procedure = call_message->get_procedure(); if (!is_valid_uri(procedure)) { send_error(session_itr->second->get_transport(), call_message->get_type(), call_message->get_request_id(), "wamp.error.invalid_uri"); return; } auto procedure_registrations_itr = m_procedure_registrations.find(procedure); if (procedure_registrations_itr == m_procedure_registrations.end()) { send_error(session_itr->second->get_transport(), call_message->get_type(), call_message->get_request_id(), "wamp.error.no_such_procedure"); return; } std::shared_ptr<wamp_session> session = procedure_registrations_itr->second->get_session(); const wamp_request_id request_id = m_request_id_generator.generate(); const wamp_registration_id& registration_id = procedure_registrations_itr->second->get_registration_id(); std::unique_ptr<wamp_invocation_message> invocation_message( new wamp_invocation_message(std::move(call_message->release_zone()))); invocation_message->set_request_id(request_id); invocation_message->set_registration_id(registration_id); invocation_message->set_arguments(call_message->get_arguments()); invocation_message->set_arguments_kw(call_message->get_arguments_kw()); BONEFISH_TRACE("%1%, %2%", *session_itr->second % *invocation_message); if (!session->get_transport()->send_message(std::move(*invocation_message))) { BONEFISH_TRACE("sending invocation message to callee failed: network failure"); send_error(session_itr->second->get_transport(), call_message->get_type(), call_message->get_request_id(), "wamp.error.network_failure"); return; } else { wamp_call_options options; options.unmarshal(call_message->get_options()); unsigned timeout_ms = options.get_option_or<unsigned>("timeout", 0); // We only setup the invocation state after sending the message is successful. // This saves us from having to cleanup any state if the send fails. std::unique_ptr<wamp_dealer_invocation> dealer_invocation( new wamp_dealer_invocation(m_io_service)); dealer_invocation->set_session(session_itr->second); dealer_invocation->set_request_id(call_message->get_request_id()); dealer_invocation->set_timeout( std::bind(&wamp_dealer::invocation_timeout_handler, this, request_id, std::placeholders::_1), timeout_ms); m_pending_invocations.insert(std::make_pair(request_id, std::move(dealer_invocation))); m_pending_callee_invocations[session->get_session_id()].insert(request_id); m_pending_caller_invocations[session_id].insert(request_id); } }