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./";
115 if (getenv(
"CF_DEBUG_BYPASS_LOGIN")) {
120 if (strlen(crypted) == 0) {
121 return strlen(typed) == 0 ? true :
false;
124 const char *typed_hashed =
crypt_string(typed, crypted);
125 if (typed_hashed != NULL) {
126 return strcmp(typed_hashed, crypted) == 0;
128 LOG(
llevError,
"Could not check password with stored hash %s\n", crypted);
157 if (oldmap ==
op->map && strcmp(
op->contr->savebed_map, oldmap->
path)) {
158 LOG(
llevDebug,
"Player %s savebed location %s is invalid - going to emergency location (%s)\n",
189 if (x < 0 && y >= 0)
x=0;
190 if (y < 0 && x >= 0)
y=0;
193 if (
x != -1 ||
y != -1) {
194 LOG(
llevError,
"enter_map: supplied coordinates are not within the map! (%s: %d, %d)\n", newmap->
path,
x,
y);
206 "The exit is closed");
230 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);
246 sizeof(
op->contr->maplevel));
247 op->contr->count = 0;
258 op->contr->golem_count = 0;
275 if (oldmap != newmap) {
284 if (oldmap != NULL) {
326 for (cp = newpath; *cp !=
'\0'; cp++) {
353 cp =
const_cast<char *
>(strrchr(src,
'/'));
359 for (cp = newpath; *cp !=
'\0'; cp++) {
378 static int reference_number = 0;
381 memset(&rp, 0,
sizeof(
RMParms));
406 while (isdigit(
buf[strlen(
buf)-1]))
411 snprintf(newmap_name,
sizeof(newmap_name),
"/random/%s%04d", cp+1, reference_number++);
459 sourcemap = strchr(exitpath,
'!');
465 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);
476 sourcemap = sourcemap_buf;
482 snprintf(tmpnum,
sizeof(tmpnum),
"%d", exit_ob->
x);
483 replace(exitpath,
"%x", tmpnum, resultname,
sizeof(resultname));
485 snprintf(tmpnum,
sizeof(tmpnum),
"%d", exit_ob->
y);
486 strlcpy(tmpstring, resultname,
sizeof(tmpstring));
487 replace(tmpstring,
"%y", tmpnum, resultname,
sizeof(resultname));
489 strlcpy(tmpstring, resultname,
sizeof(tmpstring));
490 replace(tmpstring,
"%n", exit_ob->
map->
name, resultname,
sizeof(resultname));
514 "Template exit in '%s' (%d, %d) does not reference a valid "
515 "template. Make sure a template exists at '%s'.\n",
548 snprintf(tmpnum,
sizeof(tmpnum),
"%d", exit_ob->
x);
549 replace(
EXIT_PATH(exit_ob)+3,
"%x", tmpnum, resultname,
sizeof(resultname));
551 snprintf(tmpnum,
sizeof(tmpnum),
"%d", exit_ob->
y);
552 strlcpy(tmpstring, resultname,
sizeof(tmpstring));
553 replace(tmpstring,
"%y", tmpnum, resultname,
sizeof(resultname));
555 strlcpy(tmpstring, resultname,
sizeof(tmpstring));
556 replace(tmpstring,
"%n", exit_ob->
map->
name, resultname,
sizeof(resultname));
569 memset(&rp, 0,
sizeof(
RMParms));
611 if (
op->contr->followed_player) {
612 player =
op->contr->followed_player;
626 char* src = strdup(
op->map->path);
627 char* slash = strrchr(src,
'/');
638 if ((cp = strrchr(tmpc,
'_')) != NULL)
678 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);
696 LOG(
llevError,
"Fatal: Could not load emergency map!\n");
701 "You find yourself somewhere unexpected...");
706 if (
x == -1 &&
y == -1) {
728 #define PORTAL_DESTINATION_NAME "Town portal destination"
736 assert(exit_ob != NULL);
749 "You feel a force fizzling away. You feel a vibration from: %s",
buf);
756 if (
op->contr->transport)
794 if (!newmap && !strncmp(
EXIT_PATH(exit_ob),
"/random/", 8)) {
838 if (
x == -1 &&
y == -1) {
871 exit_copy->
speed = 0;
873 exit_copy->
map = exit_ob->
map;
874 if (
op->contr->last_exit) {
877 op->contr->last_exit = exit_copy;
902 int sx, sy, sx2, sy2;
904 return (
ob->x >=
x+sx2) && (
ob->x <=
x+sx) && (
ob->y >=
y+sy2) && (
ob->y <=
y+sy);
911 assert(
pl->followed_player != NULL);
913 if (followed && followed->
ob && followed->
ob->
map) {
930 "%s stops letting you follow them.",
pl->followed_player);
946 "You stop following %s.",
pl->followed_player);
961 for (flag = 1; flag != 0; ) {
973 if (!flag)
pl->ticks_played++;
975 if (
pl->followed_player) {
979 if (
pl->ob->speed_left > 0) {
1003 pl->last_save_tick += 100;
1016 pl->ob->weapon_speed_left +=
pl->ob->weapon_speed;
1017 if (
pl->ob->weapon_speed_left > 1.0)
1018 pl->ob->weapon_speed_left = 1.0;
1020 pl->socket->sounds_this_tick = 0;
1023 if (
pl->ob->casting_time > 0) {
1024 pl->ob->casting_time--;
1031 if (has_action &&
pl->ob->speed_left > 0) {
1032 pl->ob->last_heal -= 2;
1033 pl->ob->last_sp -= 2;
1034 pl->ob->last_grace -= 2;
1035 pl->ob->last_eat += 2;
1064 }
else if (
pl->ob->speed_left >
pl->ob->speed)
1065 pl->ob->speed_left =
pl->ob->speed;
1072 return op->env != NULL && strcmp(
op->env->arch->name,
"icecube") == 0;
1085 memset(&marker, 0,
sizeof(
object));
1101 if (
op->active_prev)
1102 op->active_prev->active_next =
op;
1111 op->active_next = ▮
1115 LOG(
llevError,
"BUG: process_events(): Free object on list\n");
1138 LOG(
llevError,
"BUG: process_events(): Removed object on list\n");
1149 LOG(
llevError,
"BUG: process_events(): Object %s has no speed, but is on active list\n",
op->arch->name);
1157 &&
op->type !=
MAP) {
1158 LOG(
llevError,
"BUG: process_events(): Object without map or inventory is on active list: %s (%d)\n",
op->name,
op->count);
1172 LOG(
llevError,
"BUG: process_events(): Processing object on swapped out map: %s (%d), map=%s\n",
op->name,
op->count,
op->map->path);
1178 if ((
op->anim_speed &&
op->last_anim >=
op->anim_speed)
1179 || (
op->temp_animation &&
op->last_anim >=
op->temp_anim_speed)) {
1190 if (
op->speed_left > 0) {
1197 op->speed_left -= 10;
1199 op->speed_left -= 1;
1305 LOG(
llevInfo,
"logout: %s from %s\n",
pl->ob->name,
pl->socket->host);
1307 strcpy(
pl->ob->contr->killer,
"left");
1314 if (
pl->transport &&
pl->transport->contr ==
pl) {
1318 if (
pl->transport->inv)
1319 pl->transport->contr =
pl->transport->inv->contr;
1321 pl->transport->contr = NULL;
1323 if (
pl->transport->contr) {
1329 "%s has left. You are now the captain of %s",
1348 "%s left the game.",
1360 #if !defined(_IBMR2) && !defined(___IBMR2) && defined(PERM_FILE)
1365 int i, start,
stop, forbit = 0;
1368 tm = (
struct tm *)localtime(&clock);
1371 if ((fp = fopen(
buf,
"r")) == NULL)
1374 while (fgets(
buf,
sizeof(
buf), fp)) {
1377 if (!strncmp(
buf,
"msg", 3)) {
1379 while (fgets(
buf,
sizeof(
buf), fp))
1382 }
else if (sscanf(
buf,
"%s %d%*c%d\n", day, &start, &
stop) != 3) {
1383 LOG(
llevDebug,
"Warning: Incomplete line in permission file ignored.\n");
1387 for (i = 0; i < 7; i++) {
1389 && (tm->tm_wday == i)
1390 && (tm->tm_hour >= start)
1391 && (tm->tm_hour <
stop))
1428 LOG(
llevInfo,
"Received SIGINT; shutting down...\n");
1445 LOG(
llevInfo,
"No active players in the last %ld seconds, shutting down...\n", diff);
1473 if (time_left <= 0) {
1491 "This server will shut down when all players leave.");
1501 "This server will shut down in %lu minutes.", time_left / 60);
1582 if (getuid() == 0 || geteuid() == 0) {
1584 "Running crossfire-server as root is a bad idea; aborting!\n"
1585 "Please run it again as a normal, unprivileged user.\n");
1590 #ifdef DEBUG_MALLOC_LEVEL
1591 malloc_debug(DEBUG_MALLOC_LEVEL);
1597 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)
bool map_path_unique(const char *path)
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)