Go to the documentation of this file.
48 static const int shutdown_warn_times[] = {120, 90, 60, 45, 30, 15, 10, 5, 4, 3, 2, 1};
51 static const char *
days[] = {
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"};
75 #if (defined(__FreeBSD__))
87 static const char *
const c =
88 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
116 if (strlen(crypted) == 0) {
117 return strlen(typed) == 0 ? true :
false;
120 const char *typed_hashed =
crypt_string(typed, crypted);
121 if (typed_hashed != NULL) {
122 return strcmp(typed_hashed, crypted) == 0;
124 LOG(
llevError,
"Could not check password with stored hash %s\n", crypted);
153 if (oldmap ==
op->map && strcmp(
op->contr->savebed_map, oldmap->
path)) {
154 LOG(
llevDebug,
"Player %s savebed location %s is invalid - going to emergency location (%s)\n",
185 if (x < 0 && y >= 0)
x=0;
186 if (y < 0 && x >= 0)
y=0;
189 if (
x != -1 ||
y != -1) {
190 LOG(
llevError,
"enter_map: supplied coordinates are not within the map! (%s: %d, %d)\n", newmap->
path,
x,
y);
202 "The exit is closed");
226 LOG(
llevInfo,
"enter_map: Could not find free spot for player - will dump on top of object (%s: %d, %d)\n", newmap->
path,
x,
y);
242 sizeof(
op->contr->maplevel));
243 op->contr->count = 0;
254 op->contr->golem_count = 0;
271 if (oldmap != newmap) {
280 if (oldmap != NULL) {
337 for (cp = newpath; *cp !=
'\0'; cp++) {
364 cp =
const_cast<char *
>(strrchr(src,
'/'));
370 for (cp = newpath; *cp !=
'\0'; cp++) {
389 static int reference_number = 0;
392 memset(&rp, 0,
sizeof(
RMParms));
417 while (isdigit(
buf[strlen(
buf)-1]))
422 snprintf(newmap_name,
sizeof(newmap_name),
"/random/%s%04d", cp+1, reference_number++);
470 sourcemap = strchr(exitpath,
'!');
476 LOG(
llevError,
"enter_fixed_template_map: Exit %s (%d,%d) on map %s has no source template.\n", exit_ob->
name, exit_ob->
x, exit_ob->
y, exit_ob->
map->
path);
487 sourcemap = sourcemap_buf;
493 snprintf(tmpnum,
sizeof(tmpnum),
"%d", exit_ob->
x);
494 replace(exitpath,
"%x", tmpnum, resultname,
sizeof(resultname));
496 snprintf(tmpnum,
sizeof(tmpnum),
"%d", exit_ob->
y);
497 strlcpy(tmpstring, resultname,
sizeof(tmpstring));
498 replace(tmpstring,
"%y", tmpnum, resultname,
sizeof(resultname));
500 strlcpy(tmpstring, resultname,
sizeof(tmpstring));
501 replace(tmpstring,
"%n", exit_ob->
map->
name, resultname,
sizeof(resultname));
525 "Template exit in '%s' (%d, %d) does not reference a valid "
526 "template. Make sure a template exists at '%s'.\n",
559 snprintf(tmpnum,
sizeof(tmpnum),
"%d", exit_ob->
x);
560 replace(
EXIT_PATH(exit_ob)+3,
"%x", tmpnum, resultname,
sizeof(resultname));
562 snprintf(tmpnum,
sizeof(tmpnum),
"%d", exit_ob->
y);
563 strlcpy(tmpstring, resultname,
sizeof(tmpstring));
564 replace(tmpstring,
"%y", tmpnum, resultname,
sizeof(resultname));
566 strlcpy(tmpstring, resultname,
sizeof(tmpstring));
567 replace(tmpstring,
"%n", exit_ob->
map->
name, resultname,
sizeof(resultname));
580 memset(&rp, 0,
sizeof(
RMParms));
633 char* src = strdup(
op->map->path);
634 char* slash = strrchr(src,
'/');
645 if ((cp = strrchr(tmpc,
'_')) != NULL)
659 snprintf(apartment,
sizeof(apartment),
"~%s/%s",
op->name,
clean_path(reldir,
path,
sizeof(
path)));
685 LOG(
llevDebug,
"enter_unique_map: Exit %s (%d,%d) on map %s is leads no where.\n", exit_ob->
name, exit_ob->
x, exit_ob->
y, exit_ob->
map->
path);
703 LOG(
llevError,
"Fatal: Could not load emergency map!\n");
708 "You find yourself somewhere unexpected...");
713 if (
x == -1 &&
y == -1) {
735 #define PORTAL_DESTINATION_NAME "Town portal destination"
743 assert(exit_ob != NULL);
756 "You feel a force fizzling away. You feel a vibration from: %s",
buf);
763 if (
op->contr->transport)
801 if (!newmap && !strncmp(
EXIT_PATH(exit_ob),
"/random/", 8)) {
845 if (
x == -1 &&
y == -1) {
878 exit_copy->
speed = 0;
880 exit_copy->
map = exit_ob->
map;
881 if (
op->contr->last_exit) {
884 op->contr->last_exit = exit_copy;
909 int sx, sy, sx2, sy2;
911 return (
ob->x >=
x+sx2) && (
ob->x <=
x+sx) && (
ob->y >=
y+sy2) && (
ob->y <=
y+sy);
918 assert(
pl->followed_player != NULL);
920 if (followed && followed->
ob && followed->
ob->
map) {
937 "%s stops letting you follow them.",
pl->followed_player);
953 "You stop following %s.",
pl->followed_player);
968 for (flag = 1; flag != 0; ) {
980 if (!flag)
pl->ticks_played++;
982 if (
pl->followed_player) {
986 if (
pl->ob->speed_left > 0) {
1010 pl->last_save_tick += 100;
1023 pl->ob->weapon_speed_left +=
pl->ob->weapon_speed;
1024 if (
pl->ob->weapon_speed_left > 1.0)
1025 pl->ob->weapon_speed_left = 1.0;
1027 pl->socket->sounds_this_tick = 0;
1030 if (
pl->ob->casting_time > 0) {
1031 pl->ob->casting_time--;
1038 if (has_action &&
pl->ob->speed_left > 0) {
1039 pl->ob->last_heal -= 2;
1040 pl->ob->last_sp -= 2;
1041 pl->ob->last_grace -= 2;
1042 pl->ob->last_eat += 2;
1071 }
else if (
pl->ob->speed_left >
pl->ob->speed)
1072 pl->ob->speed_left =
pl->ob->speed;
1079 return op->env != NULL && strcmp(
op->env->arch->name,
"icecube") == 0;
1092 memset(&marker, 0,
sizeof(
object));
1108 if (
op->active_prev)
1109 op->active_prev->active_next =
op;
1118 op->active_next = ▮
1122 LOG(
llevError,
"BUG: process_events(): Free object on list\n");
1145 LOG(
llevError,
"BUG: process_events(): Removed object on list\n");
1156 LOG(
llevError,
"BUG: process_events(): Object %s has no speed, but is on active list\n",
op->arch->name);
1164 &&
op->type !=
MAP) {
1165 LOG(
llevError,
"BUG: process_events(): Object without map or inventory is on active list: %s (%d)\n",
op->name,
op->count);
1179 LOG(
llevError,
"BUG: process_events(): Processing object on swapped out map: %s (%d), map=%s\n",
op->name,
op->count,
op->map->path);
1185 if ((
op->anim_speed &&
op->last_anim >=
op->anim_speed)
1186 || (
op->temp_animation &&
op->last_anim >=
op->temp_anim_speed)) {
1197 if (
op->speed_left > 0) {
1204 op->speed_left -= 10;
1206 op->speed_left -= 1;
1312 LOG(
llevInfo,
"logout: %s from %s\n",
pl->ob->name,
pl->socket->host);
1314 strcpy(
pl->ob->contr->killer,
"left");
1321 if (
pl->transport &&
pl->transport->contr ==
pl) {
1325 if (
pl->transport->inv)
1326 pl->transport->contr =
pl->transport->inv->contr;
1328 pl->transport->contr = NULL;
1330 if (
pl->transport->contr) {
1336 "%s has left. You are now the captain of %s",
1355 "%s left the game.",
1367 #if !defined(_IBMR2) && !defined(___IBMR2) && defined(PERM_FILE)
1372 int i, start,
stop, forbit = 0;
1375 tm = (
struct tm *)localtime(&clock);
1378 if ((fp = fopen(
buf,
"r")) == NULL)
1381 while (fgets(
buf,
sizeof(
buf), fp)) {
1384 if (!strncmp(
buf,
"msg", 3)) {
1386 while (fgets(
buf,
sizeof(
buf), fp))
1389 }
else if (sscanf(
buf,
"%s %d%*c%d\n", day, &start, &
stop) != 3) {
1390 LOG(
llevDebug,
"Warning: Incomplete line in permission file ignored.\n");
1394 for (i = 0; i < 7; i++) {
1396 && (tm->tm_wday == i)
1397 && (tm->tm_hour >= start)
1398 && (tm->tm_hour <
stop))
1435 LOG(
llevInfo,
"Received SIGINT; shutting down...\n");
1452 LOG(
llevInfo,
"No active players in the last %ld seconds, shutting down...\n", diff);
1480 if (time_left <= 0) {
1498 "This server will shut down when all players leave.");
1508 "This server will shut down in %lu minutes.", time_left / 60);
1589 if (getuid() == 0 || geteuid() == 0) {
1591 "Running crossfire-server as root is a bad idea; aborting!\n"
1592 "Please run it again as a normal, unprivileged user.\n");
1597 #ifdef DEBUG_MALLOC_LEVEL
1598 malloc_debug(DEBUG_MALLOC_LEVEL);
1604 PROFILE_END(diff,
LOG(
llevInfo,
"Initialization complete (%ld ms). Waiting for connections.\n", diff/1000));
void write_book_archive(void)
#define object_was_destroyed(op, old_tag)
static bool check_shutdown(void)
int handle_newcs_player(object *op)
#define FREE_OBJ_NO_DESTROY_CALLBACK
void clean_tmp_files(void)
void tick_the_clock(void)
void remove_friendly_object(object *op)
void pets_terminate_all(object *owner)
void enter_player_savebed(object *op)
#define MSG_TYPE_ADMIN_PLAYER
void LOG(LogLevel logLevel, const char *format,...)
void free_all_readable(void)
void object_free_all_data(void)
static void enter_map(object *op, mapstruct *newmap, int x, int y)
mapstruct * ready_map_name(const char *name, int flags)
#define QUERY_FLAG(xyz, p)
void flush_old_maps(void)
void set_map_timeout(mapstruct *oldmap)
static event_registration c
StringBuffer * stringbuffer_new(void)
void object_set_enemy(object *op, object *enemy)
static void do_follow(player *pl)
int set_random_map_variable(RMParms *rp, const char *buf)
static void enter_random_map(object *pl, object *exit_ob)
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...) PRINTF_ARGS(6
int move_player(object *op, int dir)
void free_all_newserver(void)
static const flag_definition flags[]
void object_copy(const object *src_ob, object *dest_ob)
#define MAP_PLAYER_UNIQUE
#define PROFILE_BEGIN(expr)
void free_knowledge(void)
mapstruct * generate_random_map(const char *OutFileName, RMParms *RP, char **use_layout, sstring reset_group)
void cleanupPlugins(void)
void enter_player_maplevel(object *op)
void party_obsolete_parties(void)
void hiscore_check(object *op, int quiet)
static int query_flag(const object *op, int flag)
static int move_towards(object *ob, object *towards, unsigned int mindist)
#define MSG_TYPE_ADMIN_DM
#define PROFILE_END(var, expr)
static event_registration m
char * stringbuffer_finish(StringBuffer *sb)
void apply_auto_fix(mapstruct *m)
void login_check_shutdown(object *const op)
void object_free_drop_inventory(object *ob)
void write_todclock(void)
void final_free_player(player *pl)
short freearr_y[SIZEOFFREE]
static char * clean_path(const char *file, char *newpath, int size)
void query_name(const object *op, char *buf, size_t size)
char * path_combine_and_normalize(const char *src, const char *dst, char *path, size_t size)
void free_all_artifacts(void)
void clean_friendly_list(void)
void object_dump(const object *op, StringBuffer *sb)
void party_leave(object *op)
sstring add_string(const char *str)
#define FOR_OB_AND_BELOW_FINISH()
void object_get_multi_size(const object *ob, int *sx, int *sy, int *hx, int *hy)
void clean_tmp_map(mapstruct *m)
void process_events(void)
void server_main(int argc, char *argv[])
int out_of_map(mapstruct *m, int x, int y)
static void do_specials(void)
#define PORTAL_DESTINATION_NAME
char * ob_describe(const object *op, const object *observer, int use_media_tags, char *buf, size_t size)
void object_update_speed(object *op)
static bool object_on_exit(object *ob, object *exit)
void enter_exit(object *op, object *exit_ob)
char const * newhash(char const *password)
void object_free(object *ob, int flags)
#define FOR_OB_AND_BELOW_PREPARE(op_)
static void process_players1(void)
void cftimer_process_timers(void)
static bool object_in_icecube(object *op)
int ob_blocked(const object *ob, mapstruct *m, int16_t x, int16_t y)
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
void create_template_pathname(const char *name, char *buf, size_t size)
volatile sig_atomic_t shutdown_flag
void free_all_recipes(void)
size_t strlcpy(char *dst, const char *src, size_t size)
object * object_new(void)
void free_string(sstring str)
#define FREE_AND_CLEAR_STR(xyz)
void free_quest_definitions(void)
static void enter_unique_map(object *op, object *exit_ob)
#define MSG_TYPE_COMMAND_FAILURE
bool can_follow(object *, player *)
void player_map_change_common(object *op, mapstruct *const oldmap, mapstruct *const newmap)
int find_dir_2(int x, int y)
void pets_attempt_follow(object *for_owner, int force)
void replace(const char *src, const char *key, const char *replacement, char *result, size_t resultsize)
object * object_find_by_type_and_slaying(const object *who, int type, const char *slaying)
int swap_map(mapstruct *map)
#define MSG_TYPE_SPELL_FAILURE
void free_style_maps(void)
bool check_password(const char *typed, const char *crypted)
static const int shutdown_warn_times[]
#define ST_CONFIRM_PASSWORD
void metaserver_update(void)
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
static void save_and_kick_all_players(void)
char * create_pathname(const char *name, char *buf, size_t size)
void write_cs_stats(void)
void animate_object(object *op, int dir)
void update_players(void)
int object_find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
static void enter_random_template_map(object *pl, object *exit_ob)
void init(int argc, char **argv)
int hit_player(object *op, int dam, object *hitter, uint32_t type, int full_hit)
method_ret ob_apply(object *op, object *applier, int aflags)
player * find_player_partial_name(const char *plname)
void map_newmap_cmd(socket_struct *ns)
int get_rangevector(object *op1, const object *op2, rv_vector *retval, int flags)
region * get_region_by_map(mapstruct *m)
int save_player(object *op, int flag)
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
void process_object(object *op)
void object_remove(object *op)
struct shutdown_s shutdown_state
void leave(player *pl, int draw_exit)
void do_some_living(object *op)
int save_map(mapstruct *m, int flag)
void check_active_maps(void)
short freearr_x[SIZEOFFREE]
static const char * days[]
static void do_shutdown(void)
mapstruct * mapfile_load(const char *map, int flags)
static void enter_fixed_template_map(object *pl, object *exit_ob)
void knowledge_process_incremental(void)
void events_execute_global_event(int eventcode,...)
#define SP_WORD_OF_RECALL
static void process_players2(void)
void player_update_bg_music(object *player)
static char * unclean_path(const char *src, char *newpath, int size)
static char const * crypt_string(char const *str, char const *salt)