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"};
70 static char const*
crypt_string(
char const str[
static 1],
char const* salt) {
71 #if defined(WIN32) || (defined(__FreeBSD__)) 83 static const char *
const c =
84 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
85 s[0] = c[
RANDOM()%(int)strlen(c)],
86 s[1] = c[
RANDOM()%(int)strlen(c)];
96 char const*
newhash(
char const password[
static 1]) {
111 if (strlen(crypted) == 0) {
112 return strlen(typed) == 0 ? true :
false;
115 const char *typed_hashed =
crypt_string(typed, crypted);
116 if (typed_hashed != NULL) {
117 return strcmp(typed_hashed, crypted) == 0;
119 LOG(
llevError,
"Could not check password with stored hash %s\n", crypted);
140 EXIT_X(tmp) = op->contr->bed_x;
141 EXIT_Y(tmp) = op->contr->bed_y;
148 if (oldmap == op->map && strcmp(op->contr->savebed_map, oldmap->
path)) {
149 LOG(
llevDebug,
"Player %s savebed location %s is invalid - going to emergency location (%s)\n",
156 EXIT_X(tmp) = op->contr->bed_x;
157 EXIT_Y(tmp) = op->contr->bed_y;
178 LOG(
llevError,
"enter_map: supplied coordinates are not within the map! (%s: %d, %d)\n", newmap->
path, x, y);
189 "The exit is closed");
213 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);
229 sizeof(op->contr->maplevel));
230 op->contr->count = 0;
234 if (op->type == PLAYER && op->contr->ranges[
range_golem] != NULL) {
241 op->contr->golem_count = 0;
258 if (oldmap != newmap) {
267 if (oldmap != NULL) {
320 static char *
clean_path(
const char *file,
char *newpath,
int size) {
324 for (cp = newpath; *cp !=
'\0'; cp++) {
351 cp = strrchr(src,
'/');
357 for (cp = newpath; *cp !=
'\0'; cp++) {
377 static int reference_number = 0;
380 memset(&rp, 0,
sizeof(
RMParms));
405 while (isdigit(buf[strlen(buf)-1]))
406 buf[strlen(buf)-1] = 0;
410 snprintf(newmap_name,
sizeof(newmap_name),
"/random/%s%04d", cp+1, reference_number++);
452 sourcemap = strchr(exitpath,
'!');
458 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);
466 if (!exit_ob->map->is_template) {
469 sourcemap = sourcemap_buf;
475 snprintf(tmpnum,
sizeof(tmpnum),
"%d", exit_ob->x);
476 replace(exitpath,
"%x", tmpnum, resultname,
sizeof(resultname));
478 snprintf(tmpnum,
sizeof(tmpnum),
"%d", exit_ob->y);
479 strlcpy(tmpstring, resultname,
sizeof(tmpstring));
480 replace(tmpstring,
"%y", tmpnum, resultname,
sizeof(resultname));
482 strlcpy(tmpstring, resultname,
sizeof(tmpstring));
483 replace(tmpstring,
"%n", exit_ob->map->name, resultname,
sizeof(resultname));
488 if (exit_ob->map->is_template && (resultname[0] !=
'/')) {
507 "Template exit in '%s' (%d, %d) does not reference a valid " 508 "template. Make sure a template exists at '%s'.\n",
509 exit_ob->map->path, exit_ob->x, exit_ob->y, path);
541 snprintf(tmpnum,
sizeof(tmpnum),
"%d", exit_ob->x);
542 replace(
EXIT_PATH(exit_ob)+3,
"%x", tmpnum, resultname,
sizeof(resultname));
544 snprintf(tmpnum,
sizeof(tmpnum),
"%d", exit_ob->y);
545 strlcpy(tmpstring, resultname,
sizeof(tmpstring));
546 replace(tmpstring,
"%y", tmpnum, resultname,
sizeof(resultname));
548 strlcpy(tmpstring, resultname,
sizeof(tmpstring));
549 replace(tmpstring,
"%n", exit_ob->map->name, resultname,
sizeof(resultname));
554 if (exit_ob->map->is_template && (resultname[0] !=
'/')) {
562 memset(&rp, 0,
sizeof(
RMParms));
613 if (exit_ob->map->unique) {
614 unclean_path(exit_ob->map->path, reldir,
sizeof(reldir));
619 if ((cp = strrchr(tmpc,
'_')) != NULL)
633 snprintf(apartment,
sizeof(apartment),
"~%s/%s", op->name,
clean_path(reldir, path,
sizeof(path)));
659 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);
664 int flags = 0, x = op->x, y = op->y;
668 assert(op->type == PLAYER);
677 LOG(
llevError,
"Fatal: Could not load emergency map!\n");
682 "You find yourself somewhere unexpected...");
687 if (x == -1 && y == -1) {
709 #define PORTAL_DESTINATION_NAME "Town portal destination" 714 if (op->type != PLAYER)
718 if (op->contr->transport)
721 assert(exit_ob != NULL);
759 if (!newmap && !strncmp(
EXIT_PATH(exit_ob),
"/random/", 8)) {
777 if (exit_ob->stats.dam && op->type == PLAYER)
778 hit_player(op, exit_ob->stats.dam, exit_ob, exit_ob->attacktype, 1);
803 if (x == -1 && y == -1) {
820 op->contr->bed_x =
EXIT_X(exit_ob), op->contr->bed_y =
EXIT_Y(exit_ob);
830 if (exit_ob->stats.dam && op->type == PLAYER)
831 hit_player(op, exit_ob->stats.dam, exit_ob, exit_ob->attacktype, 1);
844 for (flag = 1; flag != 0; ) {
861 if (followed && followed->
ob && followed->
ob->map) {
880 if (pl->
ob->speed_left > 0) {
904 pl->last_save_tick += 100;
907 pl->last_save_tick =
pticks;
917 pl->
ob->weapon_speed_left += pl->
ob->weapon_speed;
918 if (pl->
ob->weapon_speed_left > 1.0)
919 pl->
ob->weapon_speed_left = 1.0;
924 if (pl->
ob->casting_time > 0) {
925 pl->
ob->casting_time--;
932 if (has_action && pl->
ob->speed_left > 0) {
933 pl->
ob->last_heal -= 2;
934 pl->
ob->last_sp -= 2;
935 pl->
ob->last_grace -= 2;
936 pl->
ob->last_eat += 2;
965 }
else if (pl->
ob->speed_left > pl->
ob->speed)
966 pl->
ob->speed_left = pl->
ob->speed;
973 return op->env != NULL && strcmp(op->env->arch->name,
"icecube") == 0;
986 memset(&marker, 0,
sizeof(
object));
990 if (marker.active_next)
991 marker.active_next->active_prev = ▮
992 marker.active_prev = NULL;
995 while (marker.active_next) {
996 op = marker.active_next;
1000 op->active_prev = marker.active_prev;
1002 if (op->active_prev)
1003 op->active_prev->active_next = op;
1007 marker.active_next = op->active_next;
1009 if (marker.active_next)
1010 marker.active_next->active_prev = ▮
1011 marker.active_prev = op;
1012 op->active_next = ▮
1016 LOG(
llevError,
"BUG: process_events(): Free object on list\n");
1033 && op->type != PLAYER
1039 LOG(
llevError,
"BUG: process_events(): Removed object on list\n");
1050 LOG(
llevError,
"BUG: process_events(): Object %s has no speed, but is on active list\n", op->arch->name);
1058 && op->type != MAP) {
1059 LOG(
llevError,
"BUG: process_events(): Object without map or inventory is on active list: %s (%d)\n", op->name, op->count);
1073 LOG(
llevError,
"BUG: process_events(): Processing object on swapped out map: %s (%d), map=%s\n", op->name, op->count, op->map->path);
1079 if ((op->anim_speed && op->last_anim >= op->anim_speed)
1080 || (op->temp_animation && op->last_anim >= op->temp_anim_speed)) {
1082 if ((op->type == PLAYER) || (op->type == MONSTER))
1091 if (op->speed_left > 0) {
1095 if (op->type != PLAYER) {
1098 op->speed_left -= 10;
1100 op->speed_left -= 1;
1104 if (object_was_destroyed(op, tag))
1108 op->speed_left +=
FABS(op->speed);
1115 if (marker.active_prev != NULL)
1116 marker.active_prev->active_next = NULL;
1204 strcpy(pl->
ob->contr->killer,
"left");
1226 "%s has left. You are now the captain of %s",
1227 pl->
ob->name, name);
1236 pl->
ob->type = DEAD_OBJECT;
1245 "%s left the game.",
1257 #if !defined(_IBMR2) && !defined(___IBMR2) && defined(PERM_FILE) 1262 int i, start, stop, forbit = 0;
1265 tm = (
struct tm *)localtime(&clock);
1268 if ((fp = fopen(buf,
"r")) == NULL)
1271 while (fgets(buf,
sizeof(buf), fp)) {
1274 if (!strncmp(buf,
"msg", 3)) {
1276 while (fgets(buf,
sizeof(buf), fp))
1279 }
else if (sscanf(buf,
"%s %d%*c%d\n", day, &start, &stop) != 3) {
1280 LOG(
llevDebug,
"Warning: Incomplete line in permission file ignored.\n");
1284 for (i = 0; i < 7; i++) {
1285 if (!strncmp(buf,
days[i], 3)
1286 && (tm->tm_wday == i)
1287 && (tm->tm_hour >= start)
1288 && (tm->tm_hour < stop))
1314 LOG(
llevInfo,
"Received SIGINT; shutting down...\n");
1324 static int next_warn = 0;
1337 if (time_left <= 0) {
1356 i18n(op,
"Server shutting down in %d minutes."), time_left / 60);
1438 if (getuid() == 0 || geteuid() == 0) {
1440 "Running crossfire-server as root is a bad idea; aborting!\n" 1441 "Please run it again as a normal, unprivileged user.\n");
1446 #ifdef DEBUG_MALLOC_LEVEL 1447 malloc_debug(DEBUG_MALLOC_LEVEL);
1453 LOG(
llevInfo,
"Initialization complete. Waiting for connections.\n");
void enter_exit(object *op, object *exit_ob)
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
int find_dir_2(int x, int y)
char const * newhash(char const password[static 1])
void leave(player *pl, int draw_exit)
mapstruct * mapfile_load(const char *map, int flags)
mapstruct * generate_random_map(const char *OutFileName, RMParms *RP, char **use_layout)
void object_free(object *ob, int flags)
void player_map_change_common(object *op, mapstruct *const oldmap, mapstruct *const newmap)
static bool check_shutdown(void)
void enter_player_savebed(object *op)
void free_quest_definitions(void)
static void enter_random_map(object *pl, object *exit_ob)
static void do_specials(void)
void object_free_all_data(void)
#define MSG_TYPE_COMMAND_FAILURE
void do_some_living(object *op)
void metaserver_update(void)
char * create_pathname(const char *name, char *buf, size_t size)
int save_player(object *op, int flag)
StringBuffer * stringbuffer_new(void)
mapstruct * ready_map_name(const char *name, int flags)
void free_string(sstring str)
short freearr_x[SIZEOFFREE]
#define ST_CONFIRM_PASSWORD
region * get_region_by_map(mapstruct *m)
void update_players(void)
object * object_find_by_type_and_slaying(const object *who, int type, const char *slaying)
void party_leave(object *op)
void remove_friendly_object(object *op)
static bool object_in_icecube(object *op)
method_ret ob_apply(object *op, object *applier, int aflags)
void enter_player_maplevel(object *op)
void clean_friendly_list(void)
void pets_terminate_all(object *owner)
static void enter_unique_map(object *op, object *exit_ob)
int swap_map(mapstruct *map)
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
static const int shutdown_warn_times[]
void login_check_shutdown(object *const op)
void check_active_maps(void)
void events_execute_global_event(int eventcode,...)
short freearr_y[SIZEOFFREE]
void free_all_newserver(void)
#define MSG_TYPE_ADMIN_DM
void map_newmap_cmd(socket_struct *ns)
void object_free_drop_inventory(object *ob)
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
void flush_old_maps(void)
void object_dump(const object *op, StringBuffer *sb)
void write_todclock(void)
object * object_new(void)
static char * clean_path(const char *file, char *newpath, int size)
static void enter_fixed_template_map(object *pl, object *exit_ob)
#define MSG_TYPE_ADMIN_PLAYER
static void enter_random_template_map(object *pl, object *exit_ob)
int ob_blocked(const object *ob, mapstruct *m, int16_t x, int16_t y)
void server_main(int argc, char *argv[])
char * path_combine_and_normalize(const char *src, const char *dst, char *path, size_t size)
struct quest_definition * next
static void process_players1(void)
static void do_shutdown(void)
void pets_remove_all(void)
static char * unclean_path(const char *src, char *newpath, int size)
void hiscore_check(object *op, int quiet)
volatile sig_atomic_t shutdown_flag
#define FREE_AND_CLEAR_STR(xyz)
void process_events(void)
void tick_the_clock(void)
int process_object(object *op)
void init(int argc, char **argv)
#define QUERY_FLAG(xyz, p)
void cleanupPlugins(void)
void clean_tmp_files(void)
void knowledge_process_incremental(void)
int handle_newcs_player(object *op)
void free_all_artifacts(void)
static const flag_definition flags[]
void animate_object(object *op, int dir)
int save_map(mapstruct *m, int flag)
void free_all_recipes(void)
static char const * crypt_string(char const str[static 1], char const *salt)
void replace(const char *src, const char *key, const char *replacement, char *result, size_t resultsize)
int set_random_map_variable(RMParms *rp, const char *buf)
#define PORTAL_DESTINATION_NAME
#define MAP_PLAYER_UNIQUE
void party_obsolete_parties(void)
void write_cs_stats(void)
static void enter_map(object *op, mapstruct *newmap, int x, int y)
struct regiondef * region
void object_set_enemy(object *op, object *enemy)
int out_of_map(mapstruct *m, int x, int y)
void free_all_readable(void)
void apply_auto_fix(mapstruct *m)
void cftimer_process_timers(void)
void write_book_archive(void)
sstring add_string(const char *str)
EXTERN player * first_player
static const char * days[]
void free_style_maps(void)
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
void player_update_bg_music(object *player)
void LOG(LogLevel logLevel, const char *format,...)
void free_knowledge(void)
int object_find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
void query_name(const object *op, char *buf, size_t size)
void set_map_timeout(mapstruct *oldmap)
int hit_player(object *op, int dam, object *hitter, uint32_t type, int full_hit)
int get_rangevector(object *op1, const object *op2, rv_vector *retval, int flags)
void create_template_pathname(const char *name, char *buf, size_t size)
const char * i18n(const object *who, const char *code)
void clean_tmp_map(mapstruct *m)
player * find_player_partial_name(const char *plname)
EXTERN mapstruct * first_map
void object_update_speed(object *op)
char * stringbuffer_finish(StringBuffer *sb)
size_t strlcpy(char *dst, const char *src, size_t size)
void object_remove(object *op)
bool check_password(const char *typed, const char *crypted)
static void process_players2(void)