int ObjectResetObject() { reset_object(vobjptridx(Cur_object_index)); Update_flags |= UF_WORLD_CHANGED; return 1; }
void rt_initialize() { rpcmsg msg; reset_object(); reset_lights(); InitTextures(); if (!parinitted) { parinitted=1; msg.type=1; /* setup a ping message */ } }
// Init BSP-core int core_init() { if (!core_settings.initialized) { init_core_setting(); } if (core_settings.is_daemonize) { proc_daemonize(); } fd_init(0); log_init(); load_runtime_setting(); status_op_core(STATUS_OP_INSTANCE_ID, (size_t) core_settings.instance_id); thread_init(); save_pid(); signal_init(); socket_init(); memdb_init(); online_init(); // Load modules BSP_VALUE *val = object_get_hash_str(runtime_settings, "modules"); BSP_OBJECT *vobj = value_get_object(val); BSP_STRING *vstr = NULL; if (vobj && OBJECT_TYPE_ARRAY == vobj->type) { size_t varr_size = object_size(vobj), i; if (varr_size > MAX_MODULES) { varr_size = MAX_MODULES; } reset_object(vobj); for (i = 0; i < varr_size; i ++) { val = object_get_array(vobj, i); vstr = value_get_string(val); if (vstr) { script_load_module(vstr, 1); } } } return BSP_RTN_SUCCESS; }
static void _dump_object(BSP_OBJECT *obj, int layer) { if (!obj) { return; } int i; BSP_VALUE *val; reset_object(obj); switch (obj->type) { case OBJECT_TYPE_SINGLE : // Single fprintf(stderr, "\033[1;37mObject type : [SINGLE]\033[0m\n"); val = object_get_single(obj); _dump_value(val, layer); break; case OBJECT_TYPE_ARRAY : // Array fprintf(stderr, "\033[1;37mObject type : [ARRAY]\033[0m\n"); size_t idx = 0; for (idx = 0; idx < object_size(obj); idx ++) { for (i = 0; i <= layer; i ++) { fprintf(stderr, "\t"); } fprintf(stderr, "\033[1;35m%lld\033[0m\t=> ", (long long int) idx); val = object_get_array(obj, idx); _dump_value(val, layer); } fprintf(stderr, "\n"); break; case OBJECT_TYPE_HASH : // Dict fprintf(stderr, "\033[1;37mObject type : [HASH]\033[0m\n"); val = curr_item(obj); BSP_STRING *key; while (val) { key = curr_hash_key(obj); for (i = 0; i <= layer; i ++) { fprintf(stderr, "\t"); } if (key) { fprintf(stderr, "\033[1;33m"); write(STDERR_FILENO, STR_STR(key), STR_LEN(key)); fprintf(stderr, "\033[0m"); } else { fprintf(stderr, "### NO KEY ###"); } fprintf(stderr, "\t=> "); _dump_value(val, layer); next_item(obj); val = curr_item(obj); } fprintf(stderr, "\n"); break; case OBJECT_TYPE_UNDETERMINED : default : // Null fprintf(stderr, "\033[1;36mObject type : [UNKNOWN]\033[0m\n"); break; } return; }
// Start main loop int core_loop(void (* server_event)(BSP_CALLBACK *)) { BSP_THREAD *t = get_thread(MAIN_THREAD); if (!t) { trigger_exit(BSP_RTN_FATAL, "Main thread lost!"); } // Servers BSP_VALUE *val = object_get_hash_str(runtime_settings, "servers"); BSP_OBJECT *vobj = value_get_object(val); BSP_STRING *vstr = NULL; if (vobj && OBJECT_TYPE_ARRAY == vobj->type) { struct bsp_conf_server_t srv; BSP_OBJECT *vsrv = NULL; size_t varr_size = object_size(vobj), i; reset_object(vobj); for (i = 0; i < varr_size; i ++) { val = object_get_array(vobj, i); vsrv = value_get_object(val); if (vsrv && OBJECT_TYPE_HASH == vsrv->type) { // Default value memset(&srv, 0, sizeof(struct bsp_conf_server_t)); srv.server_inet = INET_TYPE_ANY; srv.server_sock = SOCK_TYPE_ANY; srv.def_client_type = CLIENT_TYPE_DATA; srv.def_data_type = DATA_TYPE_PACKET; val = object_get_hash_str(vsrv, "name"); vstr = value_get_string(val); srv.server_name = bsp_strndup(STR_STR(vstr), STR_LEN(vstr)); val = object_get_hash_str(vsrv, "inet"); vstr = value_get_string(val); if (vstr) { if (0 == strncasecmp(STR_STR(vstr), "ipv6", 4)) { srv.server_inet = INET_TYPE_IPV6; } else if (0 == strncasecmp(STR_STR(vstr), "ipv4", 4)) { srv.server_inet = INET_TYPE_IPV4; } else if (0 == strncasecmp(STR_STR(vstr), "local", 5)) { srv.server_inet = INET_TYPE_LOCAL; } } val = object_get_hash_str(vsrv, "sock"); vstr = value_get_string(val); if (vstr) { if (0 == strncasecmp(STR_STR(vstr), "tcp", 3)) { srv.server_sock = SOCK_TYPE_TCP; } else if (0 == strncasecmp(STR_STR(vstr), "udp", 3)) { srv.server_sock = SOCK_TYPE_UDP; } } val = object_get_hash_str(vsrv, "addr"); vstr = value_get_string(val); srv.server_addr = bsp_strndup(STR_STR(vstr), STR_LEN(vstr)); val = object_get_hash_str(vsrv, "port"); srv.server_port = (int) value_get_int(val); val = object_get_hash_str(vsrv, "heartbeat_check"); srv.heartbeat_check = (int) value_get_int(val); val = object_get_hash_str(vsrv, "debug_input"); srv.debug_hex_input = value_get_boolean(val); val = object_get_hash_str(vsrv, "debug_output"); srv.debug_hex_input = value_get_boolean(val); val = object_get_hash_str(vsrv, "max_clients"); srv.max_clients = (int) value_get_int(val); val = object_get_hash_str(vsrv, "max_packet_length"); srv.max_packet_length = (size_t) value_get_int(val); val = object_get_hash_str(vsrv, "websocket"); if (value_get_boolean(val)) { srv.def_client_type = CLIENT_TYPE_WEBSOCKET_HANDSHAKE; } val = object_get_hash_str(vsrv, "data_type"); vstr = value_get_string(val); if (vstr && 0 == strncasecmp(STR_STR(vstr), "stream", 6)) { srv.def_data_type = DATA_TYPE_STREAM; } // Add server BSP_SERVER *s; int srv_fds[MAX_SERVER_PER_CREATION], srv_ct, fd_type; int nfds = MAX_SERVER_PER_CREATION; nfds = new_server(srv.server_addr, srv.server_port, srv.server_inet, srv.server_sock, srv_fds, &nfds); for (srv_ct = 0; srv_ct < nfds; srv_ct ++) { fd_type = FD_TYPE_SOCKET_SERVER; s = (BSP_SERVER *) get_fd(srv_fds[srv_ct], &fd_type); if (s) { s->name = srv.server_name; s->heartbeat_check = srv.heartbeat_check; s->def_client_type = srv.def_client_type; s->def_data_type = srv.def_data_type; s->max_packet_length = srv.max_packet_length; s->max_clients = srv.max_clients; s->debug_hex_input = srv.debug_hex_input; s->debug_hex_output = srv.debug_hex_output; add_server(s); } else { bsp_free(srv.server_name); } } } } } // Server event if (server_event) { core_settings.on_srv_events = server_event; } // Create 1 Hz clock BSP_TIMER *tmr = new_timer(BASE_CLOCK_SEC, BASE_CLOCK_USEC, -1); tmr->on_timer = base_timer; core_settings.main_timer = tmr; dispatch_to_thread(tmr->fd, MAIN_THREAD); start_timer(tmr); // Let's go load_bootstrap(); trace_msg(TRACE_LEVEL_CORE, "Core : Main thread loop started"); thread_process((void *) t); return BSP_RTN_SUCCESS; }
/* * Despite the name, this routine takes care of several things. * It will run once every 15 minutes. * * . It will attempt to reconnect to the address server if the connection has * been lost. * . It will loop through all objects. * * . If an object is found in a state of not having done reset, and the * delay to next reset has passed, then reset() will be done. * * . If the object has a existed more than the time limit given for swapping, * then 'clean_up' will first be called in the object * * There are some problems if the object self-destructs in clean_up, so * special care has to be taken of how the linked list is used. */ static void look_for_objects_to_swap() { static int next_time; #ifndef NO_IP_DEMON extern int no_ip_demon; static int next_server_time; #endif object_t *ob; VOLATILE object_t *next_ob; error_context_t econ; #ifndef NO_IP_DEMON if (current_time >= next_server_time) { /* initialize the address server. if it is already initialized, then * this is a nop. this will cause the driver to reattempt connecting * to the address server once every 15 minutes in the event that it * has gone down. */ if (!no_ip_demon && next_server_time) init_addr_server(ADDR_SERVER_IP, ADDR_SERVER_PORT); next_server_time = current_time + 15 * 60; } #endif if (current_time < next_time) return; /* Not time to look yet */ next_time = current_time + 5 * 60; /* Next time is in 5 minutes */ /* * Objects object can be destructed, which means that next object to * investigate is saved in next_ob. If very unlucky, that object can be * destructed too. In that case, the loop is simply restarted. */ next_ob = obj_list; save_context(&econ); if (SETJMP(econ.context)) restore_context(&econ); while ((ob = (object_t *)next_ob)) { int ready_for_clean_up = 0; if (ob->flags & O_DESTRUCTED) ob = obj_list; /* restart */ next_ob = ob->next_all; /* * Check reference time before reset() is called. */ if (current_time - ob->time_of_ref > time_to_clean_up) ready_for_clean_up = 1; #if !defined(NO_RESETS) && !defined(LAZY_RESETS) /* * Should this object have reset(1) called ? */ if ((ob->flags & O_WILL_RESET) && (ob->next_reset < current_time) && !(ob->flags & O_RESET_STATE)) { debug(d_flag, ("RESET /%s\n", ob->obname)); set_eval(max_cost); reset_object(ob); if(ob->flags & O_DESTRUCTED) continue; } #endif if (time_to_clean_up > 0) { /* * Has enough time passed, to give the object a chance to * self-destruct ? Save the O_RESET_STATE, which will be cleared. * * Only call clean_up in objects that has defined such a function. * * Only if the clean_up returns a non-zero value, will it be called * again. */ if (ready_for_clean_up && (ob->flags & O_WILL_CLEAN_UP)) { int save_reset_state = ob->flags & O_RESET_STATE; svalue_t *svp; debug(d_flag, ("clean up /%s\n", ob->obname)); /* * Supply a flag to the object that says if this program is * inherited by other objects. Cloned objects might as well * believe they are not inherited. Swapped objects will not * have a ref count > 1 (and will have an invalid ob->prog * pointer). * * Note that if it is in the apply_low cache, it will also * get a flag of 1, which may cause the mudlib not to clean * up the object. This isn't bad because: * (1) one expects it is rare for objects that have untouched * long enough to clean_up to still be in the cache, especially * on busy MUDs. * (2) the ones that are are the more heavily used ones, so * keeping them around seems justified. */ push_number(ob->flags & (O_CLONE) ? 0 : ob->prog->ref); set_eval(max_cost); svp = apply(APPLY_CLEAN_UP, ob, 1, ORIGIN_DRIVER); if (ob->flags & O_DESTRUCTED) continue; if (!svp || (svp->type == T_NUMBER && svp->u.number == 0)) ob->flags &= ~O_WILL_CLEAN_UP; ob->flags |= save_reset_state; } } } pop_context(&econ); } /* look_for_objects_to_swap() */