void *act_memleak_recv_maps(void *argv) { act_memleak_mq_maps_t mq_maps; act_int_t mq_ret = -1; act_int_t m_sock = *((int *)argv); act_int_t mq_opcode; free(argv); memset(&mq_maps, 0, sizeof(act_memleak_mq_maps_t)); mq_ret = mc_socket_tcp_read(m_sock, (void *)&mq_maps, sizeof(act_memleak_mq_maps_t), 1); act_printf("%s RECV_MEM_RQ_READY %d %d %d\n", __FUNCTION__, mq_ret, mq_maps.mq_opcode, sizeof(act_memleak_mq_maps_t)); if (mq_ret < 0 ) { act_printf("read error thread_quit %d\n", pthread_self()); return NULL; } mq_opcode = mq_maps.mq_opcode; switch (mq_opcode){ case ACT_MEMLEAK_MQ_OP_MAPS: sem_wait(&mutex); act_memleak_mq_maps(&mq_maps); sem_post(&mutex); break; } return NULL; }
act_void_t act_memleak_dispaly_all_pid() { act_int_t i; for (i = 0; i < g_pid_max; i++){ act_printf("pid:%d app_name:%s\n", g_pid_table[i].pid, g_pid_table[i].name); } }
void act_memleak_send_mq_local_disp(act_memleak_avl_node_t* root, act_int_t op) { act_memleak_mem_ref_t *p_mem_ref = NULL; if (root != NULL) { p_mem_ref = (act_memleak_mem_ref_t *)root->p_value; printf("NODE :%d %p key:%x\n", p_mem_ref->status, p_mem_ref->p_mem, root->key); act_memleak_send_mq_local_disp(root->left, op); if ((op & ACT_MEMLEAK_MQ_OP_DISP_OVFLOW) &&p_mem_ref->status != ACT_MEMLEAK_MEM_ST_DFREE && (p_mem_ref->status & ACT_MEMLEAK_MEM_ST_OFLOW) && (g_bind_pid == 0 || g_bind_pid == p_mem_ref->pid)){ p_mem_ref->status |= ACT_MEMLEAK_MEM_ST_OFLOW; act_printf("MQ_OP_DISP_OVERFLOW count:%d \n", err_ovflow_count);err_ovflow_count++; act_printf("overflow memory %p pid:%d size:%d\n", p_mem_ref->p_mem, p_mem_ref->pid, p_mem_ref->mem_size); act_mem_show_func_line(); act_printf("END_MQ_OP_DISP_OVERFLOW\n\n"); } if ((op & ACT_MEMLEAK_MQ_OP_DISP_UNFREE) && (p_mem_ref->status & ACT_MEMLEAK_MEM_ST_ALLOC) && (g_bind_pid == 0 || g_bind_pid == p_mem_ref->pid)){ act_printf("MQ_OP_DISP_UNFREE count:%d\n", err_unfree_count);err_unfree_count++; act_printf("unfreed memory %p pid:%d app_name:%s size:%d\n", p_mem_ref->p_mem, p_mem_ref->pid, act_memleak_find_pid(p_mem_ref->pid), p_mem_ref->mem_size); act_mem_show_func_line(); act_printf("END_MQ_OP_DISP_UNFREE\n\n"); }else if((op & ACT_MEMLEAK_MQ_OP_DISP_DBFREE) && (p_mem_ref->status & ACT_MEMLEAK_MEM_ST_DFREE)&& (g_bind_pid == 0 || g_bind_pid == p_mem_ref->pid)){ act_printf("MQ_OP_DISP_DOUBLE FREE count:%d\n", err_dbfree_count);err_dbfree_count++; act_printf("double freed memory %p pid:%d app_name:%s size:%d\n", p_mem_ref->p_mem, p_mem_ref->pid, act_memleak_find_pid(p_mem_ref->pid), p_mem_ref->mem_size); act_mem_show_func_line(); act_printf("END_MQ_OP_DISP_DOUBLE FREE\n\n"); } act_memleak_send_mq_local_disp(root->right, op); } }
/* * Set off a trap (obj) upon character (ch) - Thoric */ ch_ret spring_trap( char_data * ch, obj_data * obj ) { int dam, typ, lev; const char *txt; ch_ret retcode; typ = obj->value[1]; lev = obj->value[2]; retcode = rNONE; switch ( typ ) { default: txt = "hit by a trap"; break; case TRAP_TYPE_POISON_GAS: txt = "surrounded by a green cloud of gas"; break; case TRAP_TYPE_POISON_DART: txt = "hit by a dart"; break; case TRAP_TYPE_POISON_NEEDLE: txt = "pricked by a needle"; break; case TRAP_TYPE_POISON_DAGGER: txt = "stabbed by a dagger"; break; case TRAP_TYPE_POISON_ARROW: txt = "struck with an arrow"; break; case TRAP_TYPE_BLINDNESS_GAS: txt = "surrounded by a red cloud of gas"; break; case TRAP_TYPE_SLEEPING_GAS: txt = "surrounded by a yellow cloud of gas"; break; case TRAP_TYPE_FLAME: txt = "struck by a burst of flame"; break; case TRAP_TYPE_EXPLOSION: txt = "hit by an explosion"; break; case TRAP_TYPE_ACID_SPRAY: txt = "covered by a spray of acid"; break; case TRAP_TYPE_ELECTRIC_SHOCK: txt = "suddenly shocked"; break; case TRAP_TYPE_BLADE: txt = "sliced by a razor sharp blade"; break; case TRAP_TYPE_SEX_CHANGE: txt = "surrounded by a mysterious aura"; break; } dam = number_range( obj->value[4], obj->value[5] ); act_printf( AT_HITME, ch, NULL, NULL, TO_CHAR, "You are %s!", txt ); act_printf( AT_ACTION, ch, NULL, NULL, TO_ROOM, "$n is %s.", txt ); --obj->value[0]; if( obj->value[0] <= 0 ) obj->extract( ); switch ( typ ) { default: case TRAP_TYPE_BLADE: retcode = damage( ch, ch, dam, TYPE_UNDEFINED ); break; case TRAP_TYPE_POISON_DART: case TRAP_TYPE_POISON_NEEDLE: case TRAP_TYPE_POISON_DAGGER: case TRAP_TYPE_POISON_ARROW: retcode = obj_cast_spell( gsn_poison, lev, ch, ch, NULL ); if( retcode == rNONE ) retcode = damage( ch, ch, dam, TYPE_UNDEFINED ); break; case TRAP_TYPE_POISON_GAS: retcode = obj_cast_spell( gsn_poison, lev, ch, ch, NULL ); break; case TRAP_TYPE_BLINDNESS_GAS: retcode = obj_cast_spell( gsn_blindness, lev, ch, ch, NULL ); break; case TRAP_TYPE_SLEEPING_GAS: retcode = obj_cast_spell( skill_lookup( "sleep" ), lev, ch, ch, NULL ); break; case TRAP_TYPE_ACID_SPRAY: retcode = obj_cast_spell( skill_lookup( "acid blast" ), lev, ch, ch, NULL ); break; case TRAP_TYPE_SEX_CHANGE: retcode = obj_cast_spell( skill_lookup( "change sex" ), lev, ch, ch, NULL ); break; case TRAP_TYPE_FLAME: retcode = obj_cast_spell( skill_lookup( "flamestrike" ), lev, ch, ch, NULL ); break; case TRAP_TYPE_EXPLOSION: retcode = obj_cast_spell( gsn_fireball, lev, ch, ch, NULL ); break; case TRAP_TYPE_ELECTRIC_SHOCK: retcode = obj_cast_spell( skill_lookup( "lightning bolt" ), lev, ch, ch, NULL ); break; } return retcode; }
mc_rv sbs_func_status_bind(mc_int_t port) { mc_int_t m_socket_id = -1; mc_int_t c_socket_id = -1; struct sockaddr_in c_sin ; mc_int_t c_sin_len = 0; pthread_t tid; act_int_t *argv; fd_set set; pthread_attr_t attr; pthread_t tid_t[256] = {0}; mc_int_t tid_s[256] = {0}; act_int_t tid_i = 0; act_int_t i = 0; sem_init(&mutex, 0, 1); FVASSERT_ACT(( m_socket_command_id = mc_socket_tcp_bind(MQ_SERVER_COMMAND_PORT)) > 0, act_printf("please set ipaddress as \"192.168.1.80\"\n");exit(-1)); FVASSERT_ACT(( m_socket_maps_id = mc_socket_tcp_bind(MQ_SERVER_MAPS_PORT)) > 0, act_printf("please set ipaddress as \"192.168.1.80\"\n");exit(-1)); FVASSERT_ACT(( m_socket_memref_id = mc_socket_tcp_bind(MQ_SERVER_MEMREF_PORT)) > 0, act_printf("please set ipaddress as \"192.168.1.80\"\n");exit(-1)); FVASSERT_ACT(( m_socket_profile_id = mc_socket_tcp_bind(MQ_SERVER_PROFILE_PORT)) > 0, act_printf("please set ipaddress as \"192.168.1.80\"\n");exit(-1)); while(!g_quit){ m_socket_id = -1; FD_ZERO(&set); FD_SET(m_socket_command_id, &set); FD_SET(m_socket_maps_id, &set); FD_SET(m_socket_memref_id, &set); FD_SET(m_socket_profile_id, &set); select(m_socket_profile_id+1, &set, NULL, NULL, NULL); act_printf(" memleak selecting...\n"); if (FD_ISSET(m_socket_command_id, &set)){ m_socket_id = m_socket_command_id; port = MQ_SERVER_COMMAND_PORT; }else if (FD_ISSET(m_socket_maps_id, &set)){ m_socket_id = m_socket_maps_id; port = MQ_SERVER_MAPS_PORT; }else if (FD_ISSET(m_socket_memref_id, &set)){ m_socket_id = m_socket_memref_id; port = MQ_SERVER_MEMREF_PORT; }else if (FD_ISSET(m_socket_profile_id, &set)){ m_socket_id = m_socket_profile_id; port = MQ_SERVER_PROFILE_PORT; } if (m_socket_id > 0){ c_socket_id = accept(m_socket_id, (struct sockaddr *)&c_sin, (socklen_t *)&c_sin_len); act_printf("accepit....%d %d\n", port, c_socket_id); if (c_socket_id < 0){ continue; }else if (g_quit != 0){ break; } argv = (int *)malloc(sizeof(int)); *argv = c_socket_id; pthread_attr_init(&attr); switch(port){ case MQ_SERVER_COMMAND_PORT: pthread_create(&tid, &attr, act_memleak_recv_command, argv ); break; case MQ_SERVER_MAPS_PORT: pthread_create(&tid, &attr, act_memleak_recv_maps, argv ); break; case MQ_SERVER_MEMREF_PORT: pthread_create(&tid, &attr, act_memleak_recv_memref, argv ); break; case MQ_SERVER_PROFILE_PORT: pthread_create(&tid, &attr, act_memleak_recv_profile,argv ); break; default: break; } tid_t[tid_i] = tid; tid_s[tid_i++] = c_socket_id; if (tid_i >= 256){ tid_i = 0; } } } printf("begin main bind quit\n"); for(i = 0; i < tid_i; i++){ shutdown(tid_s[i], SHUT_RDWR); pthread_join(tid_t[i], NULL); } printf("main bind quit\n"); return MC_RV_SUC; }
void *act_memleak_recv_mq_thread(void *argv) { act_int_t i = 0; act_memleak_mq_t mq_mem_ref; act_memleak_mq_t1 *p_mem_ref1; int mq_ret = -1; int m_sock = *((int *)argv); act_memleak_avl_node_t **pp_mem_root; act_memleak_ref_root_t *p_ref_root; act_char_t programe[32] = "\0"; free(argv); while(1){ memset(&mq_mem_ref, 0, sizeof(mq_mem_ref)); mq_ret = mc_socket_tcp_read(m_sock, (void *)&mq_mem_ref, sizeof(mq_mem_ref), 1); printf("RECV_MEM_RQ_READY %d %d\n", mq_ret, mq_mem_ref.mq_opcode); if (mq_ret < 0 ) { printf("read error thread_quit %d %s\n", pthread_self(), programe); return NULL; } if (mq_mem_ref.mq_opcode == ACT_MEMLEAK_MQ_OP_MAPS){ sem_wait(&mutex); act_memleak_mq_maps((act_memleak_mq_t1 *)&mq_mem_ref, programe); sem_post(&mutex); continue; } if (big2little){ mq_mem_ref.pid = int_big2little(mq_mem_ref.pid); mq_mem_ref.p_mem = (act_uint_t *)int_big2little((act_uint_t)mq_mem_ref.p_mem); mq_mem_ref.mem_size = int_big2little(mq_mem_ref.mem_size); mq_mem_ref.time = int_big2little(mq_mem_ref.time); for (i = 0; i < ACT_MEMLEAK_MAX_STACK; i++){ mq_mem_ref.stack_index[i] = int_big2little(mq_mem_ref.stack_index[i]); } } if (mq_mem_ref.mq_opcode == ACT_MEMLEAK_MQ_OP_QUIT){ g_quit = 1; shutdown(m_socket_id, SHUT_RDWR); return NULL; }else if (mq_mem_ref.mq_opcode == ACT_MEMLEAK_MQ_OP_CLR){ act_printf("MQ_CLR\n"); sem_wait(&mutex); act_memleak_mem_ref_cleanup(&gp_preload_mem_ref_root); act_memleak_ref_root_cleanup(); act_memleak_mem_statics_ref_cleanup(); act_memleak_profile_func_cleanup(); g_pid_max = 0; sem_post(&mutex); act_printf("CATCH CLR\n\n"); }else if (mq_mem_ref.mq_opcode == ACT_MEMLEAK_MQ_OP_SEGV){ act_printf("MQ_SEGV\n"); act_memleak_func_ra_display(mq_mem_ref.pid, mq_mem_ref.stack_index); act_printf("CATCH SEGV\n\n"); }else if (mq_mem_ref.mq_opcode == ACT_MEMLEAK_MQ_OP_ADD ){ printf("MQ_OP_ADD %d 0x%x time:%d\n", mq_mem_ref.pid, mq_mem_ref.p_mem, mq_mem_ref.time); sem_wait(&mutex); if ((act_uint_t)mq_mem_ref.p_mem > 0x50000000UL){ pp_mem_root = &gp_preload_mem_ref_root; }else { p_ref_root = act_memleak_ref_root_find(mq_mem_ref.pid); pp_mem_root = &p_ref_root->p_mem_ref_root; } act_memleak_mem_ref_add(pp_mem_root, mq_mem_ref.p_mem, mq_mem_ref.mem_size, mq_mem_ref.stack_index, mq_mem_ref.pid); sem_post(&mutex); printf("END_MQ_OP_ADD\n\n"); }else if (mq_mem_ref.mq_opcode == ACT_MEMLEAK_MQ_OP_OVL ){ act_printf("MQ_OP_OVL\n"); sem_wait(&mutex); if ((act_uint_t)mq_mem_ref.p_mem >0x50000000UL){ pp_mem_root = &gp_preload_mem_ref_root; }else { p_ref_root = act_memleak_ref_root_find(mq_mem_ref.pid); pp_mem_root = &p_ref_root->p_mem_ref_root; } act_memleak_mem_ref_mod(pp_mem_root, (act_uint_t)mq_mem_ref.p_mem, ACT_MEMLEAK_MEM_ST_OFLOW); sem_post(&mutex); printf("END_MQ_OP_OVL\n\n"); }else if (mq_mem_ref.mq_opcode == ACT_MEMLEAK_MQ_OP_UOVL ){ act_printf("MQ_OP_UOVL\n"); sem_wait(&mutex); if ((act_uint_t)mq_mem_ref.p_mem >0x50000000UL){ pp_mem_root = &gp_preload_mem_ref_root; }else { p_ref_root = act_memleak_ref_root_find(mq_mem_ref.pid); pp_mem_root = &p_ref_root->p_mem_ref_root; } act_memleak_mem_ref_mod(pp_mem_root, (act_uint_t)mq_mem_ref.p_mem, ACT_MEMLEAK_MEM_ST_UOFLOW); sem_post(&mutex); printf("END_MQ_OP_OVL\n\n"); }else if (mq_mem_ref.p_mem != NULL && mq_mem_ref.mq_opcode == ACT_MEMLEAK_MQ_OP_DEL ){ printf("MQ_OP_DEL %d 0x%x time:%d\n", mq_mem_ref.pid, mq_mem_ref.p_mem, mq_mem_ref.time); sem_wait(&mutex); if ((act_uint_t)mq_mem_ref.p_mem >0x50000000UL){ pp_mem_root = &gp_preload_mem_ref_root; }else { p_ref_root = act_memleak_ref_root_find(mq_mem_ref.pid); pp_mem_root = &p_ref_root->p_mem_ref_root; } act_memleak_mem_ref_del(pp_mem_root, (act_uint_t)mq_mem_ref.p_mem, mq_mem_ref.stack_index, mq_mem_ref.pid); sem_post(&mutex); printf("END_MQ_OP_DEL\n"); }else if (mq_mem_ref.mq_opcode == ACT_MEMLEAK_MQ_OP_DISP){ act_printf("MQ_OP_DISP\n"); err_dbfree_count = 1; err_unfree_count = 1; err_ovflow_count = 1; g_statics_display_unfree = 0; act_memleak_mem_statics_ref_all_display(); act_printf("END_MQ_OP_DISP\n"); }else if (mq_mem_ref.mq_opcode == ACT_MEMLEAK_MQ_OP_DISP_UNFREE){ act_printf("MQ_OP_DISP_UNFREE\n"); err_unfree_count = 1; g_statics_display_unfree = 1; act_memleak_mem_statics_ref_all_display(); #if 0 act_memleak_send_mq_local_disp(gp_preload_mem_ref_root, ACT_MEMLEAK_MQ_OP_DISP_UNFREE); if (g_bind_pid == 0 ){ for (i = 0; i < g_pid_max; i++){ p_ref_root = act_memleak_ref_root_find(g_pid_table[i].pid); pp_mem_root = &p_ref_root->p_mem_ref_root; act_memleak_send_mq_local_disp(*pp_mem_root, ACT_MEMLEAK_MQ_OP_DISP_UNFREE); } }else { p_ref_root = act_memleak_ref_root_find(g_bind_pid); pp_mem_root = &p_ref_root->p_mem_ref_root; act_memleak_send_mq_local_disp(*pp_mem_root, ACT_MEMLEAK_MQ_OP_DISP_UNFREE); } #endif act_printf("END_MQ_OP_DISP_UNFREE\n"); }else if (mq_mem_ref.mq_opcode == ACT_MEMLEAK_MQ_OP_DISP_DBFREE){ act_printf("MQ_OP_DISP_DBFREE\n"); err_dbfree_count = 1; act_memleak_send_mq_local_disp(gp_preload_mem_ref_root, ACT_MEMLEAK_MQ_OP_DISP_DBFREE); if (g_bind_pid == 0 ){ for (i = 0; i < g_pid_max; i++){ p_ref_root = act_memleak_ref_root_find(g_pid_table[i].pid); pp_mem_root = &p_ref_root->p_mem_ref_root; act_memleak_send_mq_local_disp(*pp_mem_root, ACT_MEMLEAK_MQ_OP_DISP_DBFREE); } }else { p_ref_root = act_memleak_ref_root_find(g_bind_pid); pp_mem_root = &p_ref_root->p_mem_ref_root; act_memleak_send_mq_local_disp(*pp_mem_root, ACT_MEMLEAK_MQ_OP_DISP_DBFREE); } act_printf("END_MQ_OP_DISP_DBFREE\n"); }else if (mq_mem_ref.mq_opcode == ACT_MEMLEAK_MQ_OP_DISP_OVFLOW){ act_printf("MQ_OP_DISP_OVFLOW\n"); err_ovflow_count = 1; act_memleak_mem_statics_ref_all_overflow_display(); #if 0 act_memleak_send_mq_local_disp(gp_preload_mem_ref_root, ACT_MEMLEAK_MQ_OP_DISP_OVFLOW); if (g_bind_pid == 0 ){ for (i = 0; i < g_pid_max; i++){ p_ref_root = act_memleak_ref_root_find(g_pid_table[i].pid); pp_mem_root = &p_ref_root->p_mem_ref_root; act_memleak_send_mq_local_disp(*pp_mem_root, ACT_MEMLEAK_MQ_OP_DISP_OVFLOW); } }else { p_ref_root = act_memleak_ref_root_find(g_bind_pid); pp_mem_root = &p_ref_root->p_mem_ref_root; act_memleak_send_mq_local_disp(*pp_mem_root, ACT_MEMLEAK_MQ_OP_DISP_OVFLOW); } #endif act_printf("END_MQ_OP_DISP_OVFLOW\n"); }else if (mq_mem_ref.mq_opcode == ACT_MEMLEAK_MQ_OP_PROFILE_ADD){ printf("MQ_OP_PROFILE_ADD\n"); p_mem_ref1 = (act_memleak_mq_t1 *)&mq_mem_ref; act_memleak_profile_func_add(p_mem_ref1->u.profile.caller_pc, p_mem_ref1->u.profile.self_pc, p_mem_ref1->u.profile.time, p_mem_ref1->pid); printf("END_MQ_OP_PROFILE_ADD\n"); }else if (mq_mem_ref.mq_opcode == ACT_MEMLEAK_MQ_OP_PROFILE_END){ printf("MQ_OP_PROFILE_END\n"); p_mem_ref1 = (act_memleak_mq_t1 *)&mq_mem_ref; act_memleak_profile_func_end(p_mem_ref1->pid, p_mem_ref1->u.profile.time); printf("END_MQ_OP_PROFILE_END\n"); }else if (mq_mem_ref.mq_opcode == ACT_MEMLEAK_MQ_OP_PROFILE_DISP){ act_memleak_profile_func_stat_cleanup(); act_printf("MQ_OP_PROFILE_DISP\n"); if (g_bind_pid == 0 ){ for (i = 0; i < g_pid_max; i++){ act_printf("PROFILE_DISP pid:%d app_name:%s\n", g_pid_table[i].pid, g_pid_table[i].name); act_memleak_profile_func_travel(g_bind_level, g_pid_table[i].pid); act_printf("PROFILE_DISP\n"); } }else { act_memleak_profile_func_travel(g_bind_level, g_bind_pid); } act_printf("END_MQ_OP_PROFILE_DISP\n"); }else if (mq_mem_ref.mq_opcode == ACT_MEMLEAK_MQ_OP_PROFILE_GEO){ act_printf("MQ_OP_PROFILE_STAT_DISP\n"); if (g_bind_pid == 0 ){ for (i = 0; i < g_pid_max; i++){ act_printf("PROFILE_STAT_DISP pid:%d app_name:%s\n", g_pid_table[i].pid, g_pid_table[i].name); act_memleak_profile_func_stat_disp(g_pid_table[i].pid); act_printf("PROFILE_STAT_DISP\n"); } }else { act_memleak_profile_func_stat_disp(g_bind_pid); } act_printf("END_MQ_OP_PROFILE_STAT_DISP\n"); }else{ printf("MQ_UNREASONABLE\n"); } } return NULL; }
void *act_memleak_recv_memref(void *argv) { act_int_t i = 0; act_memleak_mq_mem_t mq_mem_ref; act_int_t mq_ret = -1; act_int_t m_sock = *((int *)argv); act_memleak_avl_node_t **pp_mem_root; act_memleak_ref_root_t *p_ref_root; act_int_t mq_opcode; free(argv); while(1){ memset(&mq_mem_ref, 0, sizeof(act_memleak_mq_mem_t)); mq_ret = mc_socket_tcp_read(m_sock, (void *)&mq_mem_ref, sizeof(act_memleak_mq_mem_t), 1); printf("%s RECV_MEM_RQ_READY %d %d sizeo:%d\n", __FUNCTION__, mq_ret, mq_mem_ref.mq_opcode, sizeof(act_memleak_mq_mem_t)); if (mq_ret < 0 ) { printf("read error thread_quit %d %s\n", pthread_self(), programe); return NULL; } if (big2little){ mq_mem_ref.pid = int_big2little(mq_mem_ref.pid); mq_mem_ref.p_mem = (act_uint_t *)int_big2little((act_uint_t)mq_mem_ref.p_mem); mq_mem_ref.mem_size = int_big2little(mq_mem_ref.mem_size); for (i = 0; i < ACT_MEMLEAK_MAX_STACK; i++){ mq_mem_ref.u.stack_index[i] = int_big2little(mq_mem_ref.u.stack_index[i]); } } mq_opcode = mq_mem_ref.mq_opcode; switch (mq_opcode){ case ACT_MEMLEAK_MQ_OP_ADD: printf("MQ_OP_ADD %d 0x%x time:%d\n", mq_mem_ref.pid, mq_mem_ref.p_mem, mq_mem_ref.time); sem_wait(&mutex); if ((act_uint_t)mq_mem_ref.p_mem > 0x50000000UL){ pp_mem_root = &gp_preload_mem_ref_root; }else { p_ref_root = act_memleak_ref_root_find(mq_mem_ref.pid); pp_mem_root = &p_ref_root->p_mem_ref_root; } act_memleak_mem_ref_add(pp_mem_root, mq_mem_ref.p_mem, mq_mem_ref.mem_size, mq_mem_ref.u.stack_index, mq_mem_ref.pid); sem_post(&mutex); printf("END_MQ_OP_ADD\n\n"); break; case ACT_MEMLEAK_MQ_OP_DEL: printf("MQ_OP_DEL %d 0x%x time:%d\n", mq_mem_ref.pid, mq_mem_ref.p_mem, mq_mem_ref.time); sem_wait(&mutex); if ((act_uint_t)mq_mem_ref.p_mem >0x50000000UL){ pp_mem_root = &gp_preload_mem_ref_root; }else { p_ref_root = act_memleak_ref_root_find(mq_mem_ref.pid); pp_mem_root = &p_ref_root->p_mem_ref_root; } act_memleak_mem_ref_del(pp_mem_root, (act_uint_t)mq_mem_ref.p_mem, mq_mem_ref.u.stack_index, mq_mem_ref.pid); sem_post(&mutex); printf("END_MQ_OP_DEL\n"); break; case ACT_MEMLEAK_MQ_OP_OVL: act_printf("MQ_OP_OVL\n"); sem_wait(&mutex); if ((act_uint_t)mq_mem_ref.p_mem >0x50000000UL){ pp_mem_root = &gp_preload_mem_ref_root; }else { p_ref_root = act_memleak_ref_root_find(mq_mem_ref.pid); pp_mem_root = &p_ref_root->p_mem_ref_root; } act_memleak_mem_ref_mod(pp_mem_root, (act_uint_t)mq_mem_ref.p_mem, ACT_MEMLEAK_MEM_ST_OFLOW); sem_post(&mutex); printf("END_MQ_OP_OVL\n\n"); break; case ACT_MEMLEAK_MQ_OP_UOVL: act_printf("MQ_OP_UOVL\n"); sem_wait(&mutex); if ((act_uint_t)mq_mem_ref.p_mem >0x50000000UL){ pp_mem_root = &gp_preload_mem_ref_root; }else { p_ref_root = act_memleak_ref_root_find(mq_mem_ref.pid); pp_mem_root = &p_ref_root->p_mem_ref_root; } act_memleak_mem_ref_mod(pp_mem_root, (act_uint_t)mq_mem_ref.p_mem, ACT_MEMLEAK_MEM_ST_UOFLOW); sem_post(&mutex); printf("END_MQ_OP_OVL\n\n"); break; } } return NULL; }
void *act_memleak_recv_command(void *argv) { act_int_t i = 0; act_memleak_mq_command_t mq_command; act_int_t mq_ret = -1; act_int_t m_sock = *((int *)argv); act_memleak_avl_node_t **pp_mem_root; act_memleak_ref_root_t *p_ref_root; act_int_t mq_opcode; free(argv); while(1){ memset(&mq_command, 0, sizeof(act_memleak_mq_command_t)); mq_ret = mc_socket_tcp_read(m_sock, (void *)&mq_command, sizeof(act_memleak_mq_command_t), 1); act_printf("%s RECV_MEM_RQ_READY %d %d size:%d\n", __FUNCTION__, mq_ret, mq_command.mq_opcode, sizeof(act_memleak_mq_command_t)); if (mq_ret < 0 ) { printf("read error thread_quit %d %s\n", pthread_self(), programe); return NULL; } mq_opcode = mq_command.mq_opcode; switch (mq_opcode){ case ACT_MEMLEAK_MQ_OP_QUIT: act_printf("MQ_QUIT\n"); g_quit = 1; shutdown(m_socket_command_id, SHUT_RDWR); shutdown(m_socket_maps_id, SHUT_RDWR); shutdown(m_socket_memref_id, SHUT_RDWR); shutdown(m_socket_profile_id, SHUT_RDWR); return NULL; break; case ACT_MEMLEAK_MQ_OP_CLR: act_printf("MQ_CLR\n"); sem_wait(&mutex); act_memleak_mem_ref_cleanup(&gp_preload_mem_ref_root); act_memleak_ref_root_cleanup(); act_memleak_mem_statics_ref_cleanup(); act_memleak_profile_func_cleanup(); g_pid_max = 0; sem_post(&mutex); act_printf("CATCH CLR\n\n"); break; case ACT_MEMLEAK_MQ_OP_DISP: act_printf("MQ_OP_DISP\n"); err_dbfree_count = 1; err_unfree_count = 1; err_ovflow_count = 1; g_statics_display_unfree = 0; act_memleak_mem_statics_ref_all_display(); act_printf("END_MQ_OP_DISP\n"); break; case ACT_MEMLEAK_MQ_OP_DISP_UNFREE: act_printf("MQ_OP_DISP_UNFREE\n"); err_unfree_count = 1; g_statics_display_unfree = 1; act_memleak_mem_statics_ref_all_display(); #if 0 act_memleak_send_mq_local_disp(gp_preload_mem_ref_root, ACT_MEMLEAK_MQ_OP_DISP_UNFREE); if (g_bind_pid == 0 ){ for (i = 0; i < g_pid_max; i++){ p_ref_root = act_memleak_ref_root_find(g_pid_table[i].pid); pp_mem_root = &p_ref_root->p_mem_ref_root; act_memleak_send_mq_local_disp(*pp_mem_root, ACT_MEMLEAK_MQ_OP_DISP_UNFREE); } }else { p_ref_root = act_memleak_ref_root_find(g_bind_pid); pp_mem_root = &p_ref_root->p_mem_ref_root; act_memleak_send_mq_local_disp(*pp_mem_root, ACT_MEMLEAK_MQ_OP_DISP_UNFREE); } #endif act_printf("END_MQ_OP_DISP_UNFREE\n"); break; case ACT_MEMLEAK_MQ_OP_DISP_DBFREE: act_printf("MQ_OP_DISP_DBFREE\n"); err_dbfree_count = 1; act_memleak_send_mq_local_disp(gp_preload_mem_ref_root, ACT_MEMLEAK_MQ_OP_DISP_DBFREE); if (g_bind_pid == 0 ){ for (i = 0; i < g_pid_max; i++){ p_ref_root = act_memleak_ref_root_find(g_pid_table[i].pid); pp_mem_root = &p_ref_root->p_mem_ref_root; act_memleak_send_mq_local_disp(*pp_mem_root, ACT_MEMLEAK_MQ_OP_DISP_DBFREE); } }else { p_ref_root = act_memleak_ref_root_find(g_bind_pid); pp_mem_root = &p_ref_root->p_mem_ref_root; act_memleak_send_mq_local_disp(*pp_mem_root, ACT_MEMLEAK_MQ_OP_DISP_DBFREE); } act_printf("END_MQ_OP_DISP_DBFREE\n"); break; case ACT_MEMLEAK_MQ_OP_DISP_OVFLOW: act_printf("MQ_OP_DISP_OVFLOW\n"); err_ovflow_count = 1; act_memleak_mem_statics_ref_all_overflow_display(); #if 0 act_memleak_send_mq_local_disp(gp_preload_mem_ref_root, ACT_MEMLEAK_MQ_OP_DISP_OVFLOW); if (g_bind_pid == 0 ){ for (i = 0; i < g_pid_max; i++){ p_ref_root = act_memleak_ref_root_find(g_pid_table[i].pid); pp_mem_root = &p_ref_root->p_mem_ref_root; act_memleak_send_mq_local_disp(*pp_mem_root, ACT_MEMLEAK_MQ_OP_DISP_OVFLOW); } }else { p_ref_root = act_memleak_ref_root_find(g_bind_pid); pp_mem_root = &p_ref_root->p_mem_ref_root; act_memleak_send_mq_local_disp(*pp_mem_root, ACT_MEMLEAK_MQ_OP_DISP_OVFLOW); } #endif act_printf("END_MQ_OP_DISP_OVFLOW\n"); break; case ACT_MEMLEAK_MQ_OP_PROFILE_DISP: act_memleak_profile_func_stat_cleanup(); act_printf("MQ_OP_PROFILE_DISP\n"); if (g_bind_pid == 0 ){ for (i = 0; i < g_pid_max; i++){ act_printf("PROFILE_DISP pid:%d app_name:%s\n", g_pid_table[i].pid, g_pid_table[i].name); act_memleak_profile_func_travel(g_bind_level, g_pid_table[i].pid); act_printf("PROFILE_DISP\n"); } }else { act_memleak_profile_func_travel(g_bind_level, g_bind_pid); } act_printf("END_MQ_OP_PROFILE_DISP\n"); break; case ACT_MEMLEAK_MQ_OP_PROFILE_GEO: act_printf("MQ_OP_PROFILE_STAT_DISP\n"); if (g_bind_pid == 0 ){ for (i = 0; i < g_pid_max; i++){ act_printf("PROFILE_STAT_DISP pid:%d app_name:%s\n", g_pid_table[i].pid, g_pid_table[i].name); act_memleak_profile_func_stat_disp(g_pid_table[i].pid); act_printf("PROFILE_STAT_DISP\n"); } }else { act_memleak_profile_func_stat_disp(g_bind_pid); } act_printf("END_MQ_OP_PROFILE_STAT_DISP\n"); break; default: break; } } return NULL; }
act_rv_t act_memleak_mq_maps(act_memleak_mq_maps_t *p_mq_ref1) { act_int_t i; act_memleak_avl_node_t **pp_func_root; act_memleak_avl_node_t **pp_file_line_root; act_memleak_ref_root_t *p_ref_root; if (big2little){ p_mq_ref1->pid = int_big2little(p_mq_ref1->pid); } for(i = 0; i < MAPS_MAX; i++){ if (big2little){ p_mq_ref1->u.maps[i].add1 = int_big2little(p_mq_ref1->u.maps[i].add1); p_mq_ref1->u.maps[i].add2 = int_big2little(p_mq_ref1->u.maps[i].add2); p_mq_ref1->u.maps[i].add3 = int_big2little(p_mq_ref1->u.maps[i].add3); p_mq_ref1->u.maps[i].add4 = int_big2little(p_mq_ref1->u.maps[i].add4); } act_printf("add1=0x%x add2=0x%x add3=0x%x add4=0x%x name:%s\n", p_mq_ref1->u.maps[i].add1, p_mq_ref1->u.maps[i].add2, p_mq_ref1->u.maps[i].add3, p_mq_ref1->u.maps[i].add4, p_mq_ref1->u.maps[i].name); } p_ref_root = act_memleak_ref_root_find(p_mq_ref1->pid); pp_func_root = &p_ref_root->p_func_ref_root; pp_file_line_root = &p_ref_root->p_file_line_ref_root; if (p_mq_ref1->u.maps[MAPS_MAIN].add1 != 0){ parse_elf(pp_func_root, pp_file_line_root, p_mq_ref1->u.maps[MAPS_MAIN].name, 0, 0, 0); //sprintf(p_name, "%s", p_mq_ref1->u.maps[MAPS_MAIN].name); } if (p_mq_ref1->u.maps[MAPS_LIB_CMS_CORE].add1 != 0){ parse_elf(pp_func_root, pp_file_line_root, "./libdbus.so", p_mq_ref1->u.maps[MAPS_LIB_CMS_CORE].add1, p_mq_ref1->u.maps[MAPS_LIB_CMS_CORE].add2, p_mq_ref1->u.maps[MAPS_LIB_CMS_CORE].add3); } if (p_mq_ref1->u.maps[MAPS_LIB_CMS_UTIL].add1 != 0){ parse_elf(pp_func_root, pp_file_line_root, "./libuClibc-0.9.30.1.so", p_mq_ref1->u.maps[MAPS_LIB_CMS_UTIL].add1, p_mq_ref1->u.maps[MAPS_LIB_CMS_UTIL].add2, p_mq_ref1->u.maps[MAPS_LIB_CMS_UTIL].add3); } if (p_mq_ref1->u.maps[MAPS_LIB_CMS_CORE].add1 != 0){ parse_elf(pp_func_root, pp_file_line_root, "./libcms_core.so", p_mq_ref1->u.maps[MAPS_LIB_CMS_CORE].add1, p_mq_ref1->u.maps[MAPS_LIB_CMS_CORE].add2, p_mq_ref1->u.maps[MAPS_LIB_CMS_CORE].add3); } if (p_mq_ref1->u.maps[MAPS_LIB_CMS_UTIL].add1 != 0){ parse_elf(pp_func_root, pp_file_line_root, "./libcms_util.so", p_mq_ref1->u.maps[MAPS_LIB_CMS_UTIL].add1, p_mq_ref1->u.maps[MAPS_LIB_CMS_UTIL].add2, p_mq_ref1->u.maps[MAPS_LIB_CMS_UTIL].add3); } if (p_mq_ref1->u.maps[MAPS_LIB_CMS_DAL].add1 != 0){ parse_elf(pp_func_root, pp_file_line_root, "./libcms_dal.so", p_mq_ref1->u.maps[MAPS_LIB_CMS_DAL].add1, p_mq_ref1->u.maps[MAPS_LIB_CMS_DAL].add2, p_mq_ref1->u.maps[MAPS_LIB_CMS_DAL].add3); } if (p_mq_ref1->u.maps[MAPS_LIB_CMS_MSG].add1 != 0){ parse_elf(pp_func_root, pp_file_line_root, "./libcms_msg.so", p_mq_ref1->u.maps[MAPS_LIB_CMS_MSG].add1, p_mq_ref1->u.maps[MAPS_LIB_CMS_MSG].add2, p_mq_ref1->u.maps[MAPS_LIB_CMS_MSG].add3); } if (p_mq_ref1->u.maps[MAPS_LIB_NANO_XML].add1 != 0){ parse_elf(pp_func_root, pp_file_line_root, "./libnanoxml.so", p_mq_ref1->u.maps[MAPS_LIB_NANO_XML].add1, p_mq_ref1->u.maps[MAPS_LIB_NANO_XML].add2, p_mq_ref1->u.maps[MAPS_LIB_NANO_XML].add3); } if (p_mq_ref1->u.maps[MAPS_LIB_XDSL_CTL].add1 != 0){ parse_elf(pp_func_root, pp_file_line_root, "./libxdslctl.so", p_mq_ref1->u.maps[MAPS_LIB_XDSL_CTL].add1, p_mq_ref1->u.maps[MAPS_LIB_XDSL_CTL].add2, p_mq_ref1->u.maps[MAPS_LIB_XDSL_CTL].add3); } if (p_mq_ref1->u.maps[MAPS_LIB_ATM_CTL].add1 != 0){ parse_elf(pp_func_root, pp_file_line_root, "./libatmctl.so", p_mq_ref1->u.maps[MAPS_LIB_ATM_CTL].add1, p_mq_ref1->u.maps[MAPS_LIB_ATM_CTL].add2, p_mq_ref1->u.maps[MAPS_LIB_ATM_CTL].add3); } if (p_mq_ref1->u.maps[MAPS_LIB_CMS_BOARD_CTL].add1 != 0){ parse_elf(pp_func_root, pp_file_line_root, "./libcms_boardctl.so", p_mq_ref1->u.maps[MAPS_LIB_CMS_BOARD_CTL].add1, p_mq_ref1->u.maps[MAPS_LIB_CMS_BOARD_CTL].add2, p_mq_ref1->u.maps[MAPS_LIB_CMS_BOARD_CTL].add3); } if (p_mq_ref1->u.maps[MAPS_LIB_WL_MNGR].add1 != 0){ parse_elf(pp_func_root, pp_file_line_root, "./libwlmngr.so", p_mq_ref1->u.maps[MAPS_LIB_WL_MNGR].add1, p_mq_ref1->u.maps[MAPS_LIB_WL_MNGR].add2, p_mq_ref1->u.maps[MAPS_LIB_WL_MNGR].add3); } if (p_mq_ref1->u.maps[MAPS_LIB_WL_CTL].add1 != 0){ parse_elf(pp_func_root, pp_file_line_root, "./libwlctl.so", p_mq_ref1->u.maps[MAPS_LIB_WL_CTL].add1, p_mq_ref1->u.maps[MAPS_LIB_WL_CTL].add2, p_mq_ref1->u.maps[MAPS_LIB_WL_CTL].add3); } if (p_mq_ref1->u.maps[MAPS_LIB_NVRAM].add1 != 0){ parse_elf(pp_func_root, pp_file_line_root, "./libnvram.so", p_mq_ref1->u.maps[MAPS_LIB_NVRAM].add1, p_mq_ref1->u.maps[MAPS_LIB_NVRAM].add2, p_mq_ref1->u.maps[MAPS_LIB_NVRAM].add3); } if (p_mq_ref1->u.maps[MAPS_LIB_CGI].add1 != 0){ parse_elf(pp_func_root, pp_file_line_root, "./libcgi.so", p_mq_ref1->u.maps[MAPS_LIB_CGI].add1, p_mq_ref1->u.maps[MAPS_LIB_CGI].add2, p_mq_ref1->u.maps[MAPS_LIB_CGI].add3); } act_printf("END MQPS pid:%d name:%s\n", p_mq_ref1->pid, p_mq_ref1->u.maps[MAPS_MAIN].name); act_memleak_add_pid(p_mq_ref1->pid, p_mq_ref1->u.maps[MAPS_MAIN].name); return ACT_RV_SUC; }
/* Rehacked by Samson - had to clean up the mess */ ch_ret move_ship( char_data * ch, exit_data * pexit, int direction ) { ship_data *ship = ch->on_ship; ch_ret retcode; short door; int newx, newy, move; retcode = rNONE; if( ch->has_pcflag( PCFLAG_ONMAP ) || ch->has_actflag( ACT_ONMAP ) ) { newx = ch->mx; newy = ch->my; switch ( direction ) { default: break; case DIR_NORTH: newy = ch->my - 1; break; case DIR_EAST: newx = ch->mx + 1; break; case DIR_SOUTH: newy = ch->my + 1; break; case DIR_WEST: newx = ch->mx - 1; break; case DIR_NORTHEAST: newx = ch->mx + 1; newy = ch->my - 1; break; case DIR_NORTHWEST: newx = ch->mx - 1; newy = ch->my - 1; break; case DIR_SOUTHEAST: newx = ch->mx + 1; newy = ch->my + 1; break; case DIR_SOUTHWEST: newx = ch->mx - 1; newy = ch->my + 1; break; } if( newx == ch->mx && newy == ch->my ) return rSTOP; retcode = process_shipexit( ch, ch->cmap, newx, newy, direction ); return retcode; } room_index *in_room = ch->in_room; room_index *from_room = in_room; room_index *to_room; if( !pexit || !( to_room = pexit->to_room ) ) { ch->print( "Alas, you cannot sail that way.\r\n" ); check_sneaks( ch ); return rSTOP; } door = pexit->vdir; /* * Overland Map stuff - Samson 7-31-99 */ /* * Upgraded 4-28-00 to allow mounts and charmies to follow PC - Samson */ if( IS_EXIT_FLAG( pexit, EX_OVERLAND ) ) { if( pexit->mx < 0 || pexit->mx >= MAX_X || pexit->my < 0 || pexit->my >= MAX_Y ) { bug( "%s: Room #%d - Invalid exit coordinates: %d %d", __FUNCTION__, in_room->vnum, pexit->mx, pexit->my ); ch->print( "Oops. Something is wrong with this map exit - notify the immortals.\r\n" ); check_sneaks( ch ); return rSTOP; } if( !ch->isnpc( ) ) { enter_map( ch, pexit, pexit->mx, pexit->my, -1 ); if( ch->mount ) enter_map( ch->mount, pexit, pexit->mx, pexit->my, -1 ); list < char_data * >::iterator ich; size_t chars = from_room->people.size( ); size_t count = 0; for( ich = from_room->people.begin( ); ich != from_room->people.end( ), ( count < chars ); ) { char_data *fch = *ich; ++ich; ++count; if( fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && ( fch->position == POS_STANDING || fch->position == POS_MOUNTED ) ) { if( !fch->isnpc( ) ) { act( AT_ACTION, "The ship sails $T.", fch, NULL, dir_name[direction], TO_CHAR ); move_char( fch, pexit, 0, direction, false ); } else enter_map( fch, pexit, pexit->mx, pexit->my, -1 ); } } } else { if( !IS_EXIT_FLAG( pexit, EX_NOMOB ) ) { enter_map( ch, pexit, pexit->mx, pexit->my, -1 ); if( ch->mount ) enter_map( ch->mount, pexit, pexit->mx, pexit->my, -1 ); list < char_data * >::iterator ich; size_t chars = from_room->people.size( ); size_t count = 0; for( ich = from_room->people.begin( ); ich != from_room->people.end( ), ( count < chars ); ) { char_data *fch = *ich; ++ich; ++count; if( fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && ( fch->position == POS_STANDING || fch->position == POS_MOUNTED ) ) { if( !fch->isnpc( ) ) { act( AT_ACTION, "The ship sails $T.", fch, NULL, dir_name[direction], TO_CHAR ); move_char( fch, pexit, 0, direction, false ); } else enter_map( fch, pexit, pexit->mx, pexit->my, -1 ); } } } } check_sneaks( ch ); return rSTOP; } if( !can_move_ship( ch, pexit->to_room->sector_type ) ) { check_sneaks( ch ); return rSTOP; } if( IS_EXIT_FLAG( pexit, EX_PORTAL ) ) { ch->print( "You cannot sail a ship through that!!\r\n" ); check_sneaks( ch ); return rSTOP; } if( !ch->is_immortal( ) && !ch->isnpc( ) && ch->in_room->area != to_room->area ) { if( ch->level < to_room->area->low_hard_range ) { switch ( to_room->area->low_hard_range - ch->level ) { case 1: ch->print( "&[tell]A voice in your mind says, 'You are nearly ready to go that way...'\r\n" ); break; case 2: ch->print( "&[tell]A voice in your mind says, 'Soon you shall be ready to travel down this path... soon.'\r\n" ); break; case 3: ch->print( "&[tell]A voice in your mind says, 'You are not ready to go down that path... yet.'\r\n" ); break; default: ch->print( "&[tell]A voice in your mind says, 'You are not ready to go down that path.'\r\n" ); } check_sneaks( ch ); return rSTOP; } else if( ch->level > to_room->area->hi_hard_range ) { ch->print( "&[tell]A voice in your mind says, 'There is nothing more for you down that path.'" ); check_sneaks( ch ); return rSTOP; } } /* * Tunnels in water sectors only check for ships, not people since they're generally too small to matter */ if( to_room->tunnel > 0 ) { int count = 0; list < ship_data * >::iterator other; for( other = shiplist.begin( ); other != shiplist.end( ); ++other ) { ship_data *shp = *other; if( shp->room == to_room->vnum ) ++count; if( count >= to_room->tunnel ) { ch->print( "There are too many ships ahead to pass.\r\n" ); check_sneaks( ch ); return rSTOP; } } } move = sect_show[in_room->sector_type].move; if( ship->fuel < move && !ch->is_immortal( ) ) { ch->print( "Your ship is too low on magical energy to sail further ahead.\r\n" ); return rSTOP; } if( !str_cmp( ch->name, ship->owner ) && !ch->is_immortal( ) ) ship->fuel -= move; rprog_leave_trigger( ch ); if( ch->char_died( ) ) return global_retcode; if( !str_cmp( ch->name, ship->owner ) ) act_printf( AT_ACTION, ch, NULL, dir_name[door], TO_ROOM, "%s sails off to the $T.", ship->name.c_str( ) ); ch->from_room( ); if( ch->mount ) { rprog_leave_trigger( ch->mount ); if( ch->char_died( ) ) return global_retcode; if( ch->mount ) { ch->mount->from_room( ); if( !ch->mount->to_room( to_room ) ) log_printf( "char_to_room: %s:%s, line %d.", __FILE__, __FUNCTION__, __LINE__ ); } } if( !ch->to_room( to_room ) ) log_printf( "char_to_room: %s:%s, line %d.", __FILE__, __FUNCTION__, __LINE__ ); ship->room = to_room->vnum; check_sneaks( ch ); if( !str_cmp( ch->name, ship->owner ) ) { const char *txt = rev_exit( door ); act_printf( AT_ACTION, ch, NULL, NULL, TO_ROOM, "%s sails in from the %s.", ship->name.c_str( ), txt ); } list < char_data * >::iterator ich; size_t chars = from_room->people.size( ); size_t count = 0; for( ich = from_room->people.begin( ); ich != from_room->people.end( ), ( count < chars ); ) { char_data *fch = *ich; ++ich; ++count; if( fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && ( fch->position == POS_STANDING || fch->position == POS_MOUNTED ) ) { act( AT_ACTION, "The ship sails $T.", fch, NULL, dir_name[door], TO_CHAR ); move_char( fch, pexit, 0, direction, false ); } } interpret( ch, "look" ); return retcode; }
/* Cheap hack of process_exit from overland.c for ships */ ch_ret process_shipexit( char_data * ch, short map, short x, short y, int dir ) { int sector = get_terrain( map, x, y ), move; room_index *from_room; ship_data *ship = ch->on_ship; ch_ret retcode; short fx, fy, fmap; from_room = ch->in_room; fx = ch->mx; fy = ch->my; fmap = ch->cmap; retcode = rNONE; if( ch->has_pcflag( PCFLAG_MAPEDIT ) ) { ch->print( "Get off the ship before you start editing.\r\n" ); return rSTOP; } if( sector == SECT_EXIT ) { mapexit_data *mexit; room_index *toroom = NULL; mexit = check_mapexit( map, x, y ); if( mexit != NULL ) { if( mexit->tomap != -1 ) /* Means exit goes to another map */ { if( !can_move_ship( ch, get_terrain( mexit->tomap, mexit->therex, mexit->therey ) ) ) return rSTOP; enter_map( ch, NULL, mexit->therex, mexit->therey, mexit->tomap ); if( ch->mount ) enter_map( ch->mount, NULL, mexit->therex, mexit->therey, mexit->tomap ); list < char_data * >::iterator ich; size_t chars = from_room->people.size( ); size_t count = 0; for( ich = from_room->people.begin( ); ich != from_room->people.end( ), ( count < chars ); ) { char_data *fch = *ich; ++ich; ++count; if( fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && ( fch->position == POS_STANDING || fch->position == POS_MOUNTED ) && fch->mx == fx && fch->my == fy && fch->cmap == fmap ) { if( !fch->isnpc( ) ) { act( AT_ACTION, "The ship sails $T.", fch, NULL, dir_name[dir], TO_CHAR ); process_exit( fch, fch->cmap, x, y, dir, false ); } else enter_map( fch, NULL, mexit->therex, mexit->therey, mexit->tomap ); } } return rSTOP; } if( !( toroom = get_room_index( mexit->vnum ) ) ) { bug( "%s: Target vnum %d for map exit does not exist!", __FUNCTION__, mexit->vnum ); ch->print( "Ooops. Something bad happened. Contact the immortals ASAP.\r\n" ); return rSTOP; } if( !can_move_ship( ch, toroom->sector_type ) ) return rSTOP; if( !str_cmp( ch->name, ship->owner ) ) act_printf( AT_ACTION, ch, NULL, dir_name[dir], TO_ROOM, "%s sails off to the $T.", ship->name.c_str( ) ); ch->on_ship->room = toroom->vnum; leave_map( ch, NULL, toroom ); list < char_data * >::iterator ich; size_t chars = from_room->people.size( ); size_t count = 0; for( ich = from_room->people.begin( ); ich != from_room->people.end( ), ( count < chars ); ) { char_data *fch = *ich; ++ich; ++count; if( fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && fch->position == POS_STANDING && fch->mx == fx && fch->my == fy && fch->cmap == fmap ) { if( !fch->isnpc( ) ) { act( AT_ACTION, "The ship sails $T.", fch, NULL, dir_name[dir], TO_CHAR ); process_shipexit( fch, fch->cmap, x, y, dir ); } else leave_map( fch, ch, toroom ); } } return rSTOP; } } switch ( dir ) { default: ch->print( "Alas, you cannot go that way...\r\n" ); return rSTOP; case DIR_NORTH: if( y == -1 ) { ch->print( "You cannot sail any further north!\r\n" ); return rSTOP; } break; case DIR_EAST: if( x == MAX_X ) { ch->print( "You cannot sail any further east!\r\n" ); return rSTOP; } break; case DIR_SOUTH: if( y == MAX_Y ) { ch->print( "You cannot sail any further south!\r\n" ); return rSTOP; } break; case DIR_WEST: if( x == -1 ) { ch->print( "You cannot sail any further west!\r\n" ); return rSTOP; } break; case DIR_NORTHEAST: if( x == MAX_X || y == -1 ) { ch->print( "You cannot sail any further northeast!\r\n" ); return rSTOP; } break; case DIR_NORTHWEST: if( x == -1 || y == -1 ) { ch->print( "You cannot sail any further northwest!\r\n" ); return rSTOP; } break; case DIR_SOUTHEAST: if( x == MAX_X || y == MAX_Y ) { ch->print( "You cannot sail any further southeast!\r\n" ); return rSTOP; } break; case DIR_SOUTHWEST: if( x == -1 || y == MAX_Y ) { ch->print( "You cannot sail any further southwest!\r\n" ); return rSTOP; } break; } if( !can_move_ship( ch, sector ) ) return rSTOP; move = sect_show[sector].move; if( ship->fuel < move && !ch->is_immortal( ) ) { ch->print( "Your ship is too low on magical energy to sail further ahead.\r\n" ); return rSTOP; } if( !ch->is_immortal( ) && !str_cmp( ch->name, ship->owner ) ) ship->fuel -= move; if( !str_cmp( ch->name, ship->owner ) ) act_printf( AT_ACTION, ch, NULL, dir_name[dir], TO_ROOM, "%s sails off to the $T.", ship->name.c_str( ) ); ch->mx = x; ch->my = y; ship->mx = x; ship->my = y; if( !str_cmp( ch->name, ship->owner ) ) { const char *txt = rev_exit( dir ); act_printf( AT_ACTION, ch, NULL, NULL, TO_ROOM, "%s sails in from the %s.", ship->name.c_str( ), txt ); } list < char_data * >::iterator ich; size_t chars = from_room->people.size( ); size_t count = 0; for( ich = from_room->people.begin( ); ich != from_room->people.end( ), ( count < chars ); ) { char_data *fch = *ich; ++ich; ++count; if( fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && ( fch->position == POS_STANDING || fch->position == POS_MOUNTED ) && fch->mx == fx && fch->my == fy ) { if( !fch->isnpc( ) ) { act( AT_ACTION, "The ship sails $T.", fch, NULL, dir_name[dir], TO_CHAR ); process_exit( fch, fch->cmap, x, y, dir, false ); } else { fch->mx = x; fch->my = y; } } } interpret( ch, "look" ); return retcode; }
/* Duplicate of to_channel from act_comm.c modified for dynamic channels */ void send_tochannel( char_data * ch, mud_channel * channel, string & argument ) { int speaking = -1; for( int lang = 0; lang < LANG_UNKNOWN; ++lang ) { if( ch->speaking == lang ) { speaking = lang; break; } } if( ch->isnpc( ) && channel->type == CHAN_GUILD ) { ch->print( "Mobs can't be in clans/guilds.\r\n" ); return; } if( ch->has_pcflag( PCFLAG_SILENCE ) ) { ch->printf( "You can't %s.\r\n", channel->name.c_str( ) ); return; } if( ch->has_aflag( AFF_SILENCE ) ) { ch->print( "You are unable to utter a sound!\r\n" ); return; } if( !ch->IS_PKILL( ) && channel->type == CHAN_PK ) { if( !ch->is_immortal( ) ) { ch->print( "Peacefuls have no need to use PK channels.\r\n" ); return; } } if( ch->in_room->flags.test( ROOM_SILENCE ) || ch->in_room->flags.test( ROOM_NOYELL ) || ch->in_room->area->flags.test( AFLAG_SILENCE ) ) { ch->print( "The room absorbs your words!\r\n" ); return; } if( ch->isnpc( ) && ch->has_aflag( AFF_CHARM ) ) { if( ch->master ) ch->master->print( "I don't think so...\r\n" ); return; } if( argument.empty( ) ) { if( !channel->flags.test( CHAN_KEEPHISTORY ) ) { ch->printf( "%s what?\r\n", capitalize( channel->name ).c_str( ) ); return; } show_channel_history( ch, channel ); return; } // Adaptation of Smaug 1.8b feature. Stop whitespace abuse now! strip_spaces( argument ); string arg, word; char_data *victim = nullptr; social_type *social = nullptr; string socbuf_char, socbuf_vict, socbuf_other; arg = argument; arg = one_argument( arg, word ); if( word[0] == '@' && ( social = find_social( word.substr( 1, word.length( ) ) ) ) != nullptr ) { if( !arg.empty( ) ) { string name; one_argument( arg, name ); if( ( victim = ch->get_char_world( name ) ) ) arg = one_argument( arg, name ); if( !victim ) { socbuf_char = social->char_no_arg; socbuf_vict = social->others_no_arg; socbuf_other = social->others_no_arg; if( socbuf_char.empty( ) && socbuf_other.empty( ) ) social = nullptr; } else if( victim == ch ) { socbuf_char = social->char_auto; socbuf_vict = social->others_auto; socbuf_other = social->others_auto; if( socbuf_char.empty( ) && socbuf_other.empty( ) ) social = nullptr; } else { socbuf_char = social->char_found; socbuf_vict = social->vict_found; socbuf_other = social->others_found; if( socbuf_char.empty( ) && socbuf_other.empty( ) && socbuf_vict.empty( ) ) social = nullptr; } } else { socbuf_char = social->char_no_arg; socbuf_vict = social->others_no_arg; socbuf_other = social->others_no_arg; if( socbuf_char.empty( ) && socbuf_other.empty( ) ) social = nullptr; } } bool emote = false; if( word[0] == ',' ) { emote = true; argument = argument.substr( 1, argument.length( ) ); } if( social ) { act_printf( AT_PLAIN, ch, argument.c_str( ), victim, TO_CHAR, "&W[&[%s]%s&W] &[%s]%s", channel->colorname.c_str( ), capitalize( channel->name ).c_str( ), channel->colorname.c_str( ), socbuf_char.c_str( ) ); } else if( emote ) { ch->printf( "&W[&[%s]%s&W] &[%s]%s %s\r\n", channel->colorname.c_str( ), capitalize( channel->name ).c_str( ), channel->colorname.c_str( ), ch->name, argument.c_str( ) ); } else { if( ch->has_pcflag( PCFLAG_WIZINVIS ) ) ch->printf( "&[%s](%d) You %s '%s'\r\n", channel->colorname.c_str( ), ( !ch->isnpc( ) ? ch->pcdata->wizinvis : ch->mobinvis ), channel->name.c_str( ), argument.c_str( ) ); else ch->printf( "&[%s]You %s '%s'\r\n", channel->colorname.c_str( ), channel->name.c_str( ), argument.c_str( ) ); } if( ch->in_room->flags.test( ROOM_LOGSPEECH ) ) append_to_file( LOG_FILE, "%s: %s (%s)", ch->isnpc( )? ch->short_descr : ch->name, argument.c_str( ), channel->name.c_str( ) ); /* * Channel history. Records the last MAX_CHANHISTORY messages to channels which keep historys */ if( channel->flags.test( CHAN_KEEPHISTORY ) ) update_channel_history( ch, channel, argument, emote ); list < char_data * >::iterator ich; for( ich = pclist.begin( ); ich != pclist.end( ); ++ich ) { char_data *vch = *ich; /* * Hackish solution to stop that damned "someone chat" bug - Matarael 17.3.2002 */ bool mapped = false; int origmap = -1, origx = -1, origy = -1; if( vch == ch || !vch->desc ) continue; if( vch->desc->connected == CON_PLAYING && hasname( vch->pcdata->chan_listen, channel->name ) ) { string sbuf = argument; char lbuf[MIL + 4]; /* invis level string + buf */ if( vch->level < channel->level ) continue; if( vch->in_room->flags.test( ROOM_SILENCE ) || vch->in_room->area->flags.test( AFLAG_SILENCE ) ) continue; if( channel->type == CHAN_ROOM ) { if( vch->in_room != ch->in_room ) continue; /* * Check to see if a player on a map is at the same coords as the recipient */ if( !is_same_char_map( ch, vch ) ) continue; } if( channel->type == CHAN_ZONE && ( vch->in_room->area != ch->in_room->area || vch->in_room->flags.test( ROOM_NOYELL ) ) ) continue; if( channel->type == CHAN_PK && !vch->IS_PKILL( ) && !vch->is_immortal( ) ) continue; if( channel->type == CHAN_GUILD ) { if( vch->isnpc( ) ) continue; if( vch->pcdata->clan != ch->pcdata->clan ) continue; } int position = vch->position; vch->position = POS_STANDING; if( ch->has_pcflag( PCFLAG_WIZINVIS ) && vch->can_see( ch, false ) && vch->is_immortal( ) ) snprintf( lbuf, MIL + 4, "&[%s](%d) ", channel->colorname.c_str( ), ( !ch->isnpc( ) ) ? ch->pcdata->wizinvis : ch->mobinvis ); else lbuf[0] = '\0'; if( speaking != -1 && ( !ch->isnpc( ) || ch->speaking ) ) { int speakswell = UMIN( knows_language( vch, ch->speaking, ch ), knows_language( ch, ch->speaking, vch ) ); if( speakswell < 85 ) sbuf = translate( speakswell, argument, lang_names[speaking] ); } /* * Check to see if target is ignoring the sender */ if( is_ignoring( vch, ch ) ) { /* * If the sender is an imm then they cannot be ignored */ if( !ch->is_immortal( ) || vch->level > ch->level ) { /* * Off to oblivion! */ continue; } } MOBtrigger = false; /* * Hackish solution to stop that damned "someone chat" bug - Matarael 17.3.2002 */ if( ch->has_pcflag( PCFLAG_ONMAP ) ) { mapped = true; origx = ch->mx; origy = ch->my; origmap = ch->wmap; } if( ch->isnpc( ) && ch->has_actflag( ACT_ONMAP ) ) { mapped = true; origx = ch->mx; origy = ch->my; origmap = ch->wmap; } fix_maps( vch, ch ); char buf[MSL]; if( !social && !emote ) { snprintf( buf, MSL, "&[%s]$n %ss '$t&[%s]'", channel->colorname.c_str( ), channel->name.c_str( ), channel->colorname.c_str( ) ); mudstrlcat( lbuf, buf, MIL + 4 ); act( AT_PLAIN, lbuf, ch, sbuf.c_str( ), vch, TO_VICT ); } if( emote ) { snprintf( buf, MSL, "&W[&[%s]%s&W] &[%s]$n $t", channel->colorname.c_str( ), capitalize( channel->name ).c_str( ), channel->colorname.c_str( ) ); mudstrlcat( lbuf, buf, MIL + 4 ); act( AT_PLAIN, lbuf, ch, sbuf.c_str( ), vch, TO_VICT ); } if( social ) { if( vch == victim ) { act_printf( AT_PLAIN, ch, nullptr, vch, TO_VICT, "&W[&[%s]%s&W] &[%s]%s", channel->colorname.c_str( ), capitalize( channel->name ).c_str( ), channel->colorname.c_str( ), socbuf_vict.c_str( ) ); } else { act_printf( AT_PLAIN, ch, vch, victim, TO_THIRD, "&W[&[%s]%s&W] &[%s]%s", channel->colorname.c_str( ), capitalize( channel->name ).c_str( ), channel->colorname.c_str( ), socbuf_other.c_str( ) ); } } vch->position = position; /* * Hackish solution to stop that damned "someone chat" bug - Matarael 17.3.2002 */ if( mapped ) { ch->wmap = origmap; ch->mx = origx; ch->my = origy; if( ch->isnpc( ) ) ch->set_actflag( ACT_ONMAP ); else ch->set_pcflag( PCFLAG_ONMAP ); } else { if( ch->isnpc( ) ) ch->unset_actflag( ACT_ONMAP ); else ch->unset_pcflag( PCFLAG_ONMAP ); ch->wmap = -1; ch->mx = -1; ch->my = -1; } } } }
/* * Generic use ranged attack function -Thoric & Tricops */ ch_ret ranged_attack( char_data * ch, string argument, obj_data * weapon, obj_data * projectile, short dt, short range ) { string arg, arg1, temp; if( !argument.empty( ) && argument[0] == '\'' ) { one_argument( argument, temp ); argument = temp; } argument = one_argument( argument, arg ); argument = one_argument( argument, arg1 ); if( arg.empty( ) ) { ch->print( "Where? At who?\r\n" ); return rNONE; } /* * get an exit or a victim */ short dir = -1; exit_data *pexit; char_data *victim = nullptr; if( !( pexit = find_door( ch, arg, true ) ) ) { if( !( victim = ch->get_char_room( arg ) ) ) { ch->print( "Aim in what direction?\r\n" ); return rNONE; } else { if( ch->who_fighting( ) == victim ) { ch->print( "They are too close to release that type of attack!\r\n" ); return rNONE; } } } else dir = pexit->vdir; /* * check for ranged attacks from private rooms, etc */ if( !victim ) { if( ch->in_room->flags.test( ROOM_PRIVATE ) || ch->in_room->flags.test( ROOM_SOLITARY ) ) { ch->print( "You cannot perform a ranged attack from a private room.\r\n" ); return rNONE; } if( ch->in_room->tunnel > 0 ) { if( ( int )ch->in_room->people.size( ) >= ch->in_room->tunnel ) { ch->print( "This room is too cramped to perform such an attack.\r\n" ); return rNONE; } } } skill_type *skill = nullptr; if( IS_VALID_SN( dt ) ) skill = skill_table[dt]; if( pexit && !pexit->to_room ) { ch->print( "Are you expecting to fire through a wall!?\r\n" ); return rNONE; } /* * Check for obstruction */ if( pexit && IS_EXIT_FLAG( pexit, EX_CLOSED ) ) { if( IS_EXIT_FLAG( pexit, EX_SECRET ) || IS_EXIT_FLAG( pexit, EX_DIG ) ) ch->print( "Are you expecting to fire through a wall!?\r\n" ); else ch->print( "Are you expecting to fire through a door!?\r\n" ); return rNONE; } /* * Keeps em from firing through a wall but can still fire through an arrow slit or window, Marcus */ if( pexit ) { if( ( IS_EXIT_FLAG( pexit, EX_FORTIFIED ) || IS_EXIT_FLAG( pexit, EX_HEAVY ) || IS_EXIT_FLAG( pexit, EX_MEDIUM ) || IS_EXIT_FLAG( pexit, EX_LIGHT ) || IS_EXIT_FLAG( pexit, EX_CRUMBLING ) ) && !IS_EXIT_FLAG( pexit, EX_WINDOW ) && !IS_EXIT_FLAG( pexit, EX_ASLIT ) ) { ch->print( "Are you expecting to fire through a wall!?\r\n" ); return rNONE; } } char_data *vch = nullptr; if( pexit && !arg1.empty( ) ) { if( !( vch = scan_for_vic( ch, pexit, arg1 ) ) ) { ch->print( "You cannot see your target.\r\n" ); return rNONE; } /* * don't allow attacks on mobs that are in a no-missile room --Shaddai */ if( vch->in_room->flags.test( ROOM_NOMISSILE ) ) { ch->print( "You can't get a clean shot off.\r\n" ); return rNONE; } /* * can't properly target someone heavily in battle */ if( vch->num_fighting > MAX_FIGHT ) { ch->print( "There is too much activity there for you to get a clear shot.\r\n" ); return rNONE; } } if( vch ) { if( !vch->CAN_PKILL( ) || !ch->CAN_PKILL( ) ) { ch->print( "You can't do that!\r\n" ); return rNONE; } if( vch && is_safe( ch, vch ) ) return rNONE; } room_index *was_in_room = ch->in_room; const char *stxt = "burst of energy"; if( projectile ) { projectile->separate( ); if( pexit ) { if( weapon ) { act( AT_GREY, "You fire $p $T.", ch, projectile, dir_name[dir], TO_CHAR ); act( AT_GREY, "$n fires $p $T.", ch, projectile, dir_name[dir], TO_ROOM ); } else { act( AT_GREY, "You throw $p $T.", ch, projectile, dir_name[dir], TO_CHAR ); act( AT_GREY, "$n throw $p $T.", ch, projectile, dir_name[dir], TO_ROOM ); } } else { if( weapon ) { act( AT_GREY, "You fire $p at $N.", ch, projectile, victim, TO_CHAR ); act( AT_GREY, "$n fires $p at $N.", ch, projectile, victim, TO_NOTVICT ); act( AT_GREY, "$n fires $p at you!", ch, projectile, victim, TO_VICT ); } else { act( AT_GREY, "You throw $p at $N.", ch, projectile, victim, TO_CHAR ); act( AT_GREY, "$n throws $p at $N.", ch, projectile, victim, TO_NOTVICT ); act( AT_GREY, "$n throws $p at you!", ch, projectile, victim, TO_VICT ); } } } else if( skill ) { if( skill->noun_damage && skill->noun_damage[0] != '\0' ) stxt = skill->noun_damage; else stxt = skill->name; /* * a plain "spell" flying around seems boring */ if( !str_cmp( stxt, "spell" ) ) stxt = "magical burst of energy"; if( skill->type == SKILL_SPELL ) { if( pexit ) { act( AT_MAGIC, "You release $t $T.", ch, aoran( stxt ), dir_name[dir], TO_CHAR ); act( AT_MAGIC, "$n releases $s $t $T.", ch, stxt, dir_name[dir], TO_ROOM ); } else { act( AT_MAGIC, "You release $t at $N.", ch, aoran( stxt ), victim, TO_CHAR ); act( AT_MAGIC, "$n releases $s $t at $N.", ch, stxt, victim, TO_NOTVICT ); act( AT_MAGIC, "$n releases $s $t at you!", ch, stxt, victim, TO_VICT ); } } } else { bug( "%s: no projectile, no skill dt %d", __func__, dt ); return rNONE; } /* * victim in same room */ if( victim ) { check_illegal_pk( ch, victim ); check_attacker( ch, victim ); return ranged_got_target( ch, victim, weapon, projectile, 0, dt, stxt, AT_MAGIC ); } /* * assign scanned victim */ victim = vch; /* * reverse direction text from move_char */ const char *dtxt = rev_exit( pexit->vdir ); int dist = 0; while( dist <= range ) { ch->from_room( ); if( !ch->to_room( pexit->to_room ) ) log_printf( "char_to_room: %s:%s, line %d.", __FILE__, __func__, __LINE__ ); if( IS_EXIT_FLAG( pexit, EX_CLOSED ) ) { /* * whadoyahknow, the door's closed */ if( projectile ) ch->printf( "&wYou see your %s pierce a door in the distance to the %s.", projectile->myobj( ).c_str( ), dir_name[dir] ); else ch->printf( "&wYou see your %s hit a door in the distance to the %s.", stxt, dir_name[dir] ); if( projectile ) act_printf( AT_GREY, ch, projectile, nullptr, TO_ROOM, "$p flies in from %s and implants itself solidly in the %sern door.", dtxt, dir_name[dir] ); else act_printf( AT_GREY, ch, nullptr, nullptr, TO_ROOM, "%s flies in from %s and implants itself solidly in the %sern door.", aoran( stxt ), dtxt, dir_name[dir] ); break; } /* * no victim? pick a random one */ if( !victim ) { list < char_data * >::iterator ich; for( ich = ch->in_room->people.begin( ); ich != ch->in_room->people.end( ); ++ich ) { vch = *ich; if( ( ( ch->isnpc( ) && !vch->isnpc( ) ) || ( !ch->isnpc( ) && vch->isnpc( ) ) ) && number_bits( 1 ) == 0 ) { victim = vch; break; } } if( victim && is_safe( ch, victim ) ) { ch->from_room( ); if( !ch->to_room( was_in_room ) ) log_printf( "char_to_room: %s:%s, line %d.", __FILE__, __func__, __LINE__ ); return rNONE; } } /* * In the same room as our victim? */ if( victim && ch->in_room == victim->in_room ) { if( projectile ) act( AT_GREY, "$p flies in from $T.", ch, projectile, dtxt, TO_ROOM ); else act( AT_GREY, "$t flies in from $T.", ch, aoran( stxt ), dtxt, TO_ROOM ); /* * get back before the action starts */ ch->from_room( ); if( !ch->to_room( was_in_room ) ) log_printf( "char_to_room: %s:%s, line %d.", __FILE__, __func__, __LINE__ ); check_illegal_pk( ch, victim ); check_attacker( ch, victim ); return ranged_got_target( ch, victim, weapon, projectile, dist, dt, stxt, AT_GREY ); } if( dist == range ) { if( projectile ) { act( AT_GREY, "Your $t falls harmlessly to the ground to the $T.", ch, projectile->myobj( ).c_str( ), dir_name[dir], TO_CHAR ); act( AT_GREY, "$p flies in from $T and falls harmlessly to the ground here.", ch, projectile, dtxt, TO_ROOM ); if( projectile->in_obj ) projectile->from_obj( ); if( projectile->carried_by ) projectile->from_char( ); projectile->to_room( ch->in_room, ch ); } else { act( AT_MAGIC, "Your $t fizzles out harmlessly to the $T.", ch, stxt, dir_name[dir], TO_CHAR ); act( AT_MAGIC, "$t flies in from $T and fizzles out harmlessly.", ch, aoran( stxt ), dtxt, TO_ROOM ); } break; } if( !( pexit = ch->in_room->get_exit( dir ) ) ) { if( projectile ) { act( AT_GREY, "Your $t hits a wall and bounces harmlessly to the ground to the $T.", ch, projectile->myobj( ).c_str( ), dir_name[dir], TO_CHAR ); act( AT_GREY, "$p strikes the $Tsern wall and falls harmlessly to the ground.", ch, projectile, dir_name[dir], TO_ROOM ); if( projectile->in_obj ) projectile->from_obj( ); if( projectile->carried_by ) projectile->from_char( ); projectile->to_room( ch->in_room, ch ); } else { act( AT_MAGIC, "Your $t harmlessly hits a wall to the $T.", ch, stxt, dir_name[dir], TO_CHAR ); act( AT_MAGIC, "$t strikes the $Tsern wall and falls harmlessly to the ground.", ch, aoran( stxt ), dir_name[dir], TO_ROOM ); } break; } if( projectile ) act( AT_GREY, "$p flies in from $T.", ch, projectile, dtxt, TO_ROOM ); else act( AT_MAGIC, "$t flies in from $T.", ch, aoran( stxt ), dtxt, TO_ROOM ); ++dist; } ch->from_room( ); if( !ch->to_room( was_in_room ) ) log_printf( "char_to_room: %s:%s, line %d.", __FILE__, __func__, __LINE__ ); if( projectile->carried_by == ch ) projectile->extract( ); return rNONE; }