 |
Crossfire Server, Trunk
1.75.0
|
Go to the documentation of this file.
54 #include <sys/types.h>
55 #include <netinet/in.h>
56 #include <netinet/tcp.h>
71 #define VALIDCHAR_MSG "The first character must be alphanumeric and the last cannot be a space. None of these characters are allowed: :;/\\["
96 static int clamp(
int x,
int min,
int max) {
97 return MAX(min,
MIN(x, max));
148 if (len <= 0 || !
buf) {
168 for (;
buf[s] &&
buf[s] !=
' '; s++)
174 while (
buf[s] ==
' ')
180 for (;
buf[s] &&
buf[s] !=
' '; s++)
184 while (s < len &&
buf[s] ==
' ')
189 if (!strcmp(cmd,
"sound2")) {
192 }
else if (!strcmp(cmd,
"spellmon")) {
195 monitor_spells = atoi(param);
196 if (monitor_spells < 0 || monitor_spells > 2) {
202 }
else if (!strcmp(cmd,
"darkness")) {
205 darkness = atoi(param);
206 if (darkness != 0 && darkness != 1) {
212 }
else if (!strcmp(cmd,
"map2cmd")) {
215 map2cmd = atoi(param);
221 }
else if (!strcmp(cmd,
"facecache")) {
224 facecache = atoi(param);
225 if (facecache != 0 && facecache != 1) {
231 }
else if (!strcmp(cmd,
"faceset")) {
237 }
else if (!strcmp(cmd,
"mapsize")) {
240 if (sscanf(param,
"%dx%d%n", &x, &y, &n) != 2 || n != (
int)strlen(param)) {
249 if ((x <= 0) && (y <= 0)) {
282 }
else if (!strcmp(cmd,
"tick")) {
286 if (tick != 0 && tick != 1) {
292 }
else if (!strcmp(cmd,
"bot")) {
295 is_bot = atoi(param);
296 if (is_bot != 0 && is_bot != 1) {
302 }
else if (!strcmp(cmd,
"want_pickup")) {
312 }
else if (!strcmp(cmd,
"num_look_objects")) {
330 }
else if (!strcmp(cmd,
"extended_stats")) {
333 extended_stats = atoi(param);
334 if (extended_stats != 0 && extended_stats != 1) {
340 }
else if (!strcmp(cmd,
"beat")) {
341 int use_beat = atoi(param);
343 if (use_beat != 0 && use_beat != 1) {
351 }
else if (!strcmp(cmd,
"loginmethod")) {
354 loginmethod = atoi(param);
357 if (loginmethod > 2) loginmethod=2;
362 }
else if (!strcmp(cmd,
"notifications")) {
365 notifications = atoi(param);
370 }
else if (!strcmp(cmd,
"newmapcmd")) {
378 }
else if (!strcmp(cmd,
"extendedTextInfos")) {
384 }
else if (!strcmp(cmd,
"itemcmd")) {
390 }
else if (!strcmp(cmd,
"exp64")) {
443 "Warning: Your client is too old to receive map data. Please update to a new client at: "
444 "https://sourceforge.net/projects/crossfire/");
460 const Face *smoothface;
479 "Could not smooth face %s. "
480 "Check that this face has a smoothing pixmap, or remove its smoothlevel.\n",
506 if (len <= 0 || !
buf) {
507 LOG(
llevDebug,
"IP '%s' sent bogus ask_smooth_cmd information\n", ns->
host);
534 LOG(
llevDebug,
"Corrupt ncom command - not long enough - discarding\n");
557 "You can not issue commands - state is not ST_PLAYING (%s)",
564 LOG(
llevError,
"Player %s (%s) has negative time - shouldn't do command.\n",
591 if (len <= 0 || !
buf) {
600 LOG(
llevError,
"Got reply message with ST_PLAYING input state\n");
653 char *cs_str = strtok_r(
buf,
" ", &rest);
654 char *sc_str = strtok_r(NULL,
" ", &rest);
657 if (cs_str == NULL || sc_str == NULL) {
676 LOG(
llevInfo,
"Connection from %s (%s), CS %d, SC %d\n",
711 if (len <= 0 || !
buf) {
721 for (i = 0; i < 2; i++) {
723 if (!(
buf = strchr(
buf,
' '))) {
754 #define AddIfInt64(Old, New, sl, Type) \
757 SockList_AddChar(sl, Type); \
758 SockList_AddInt64(sl, New); \
761 #define AddIfInt(Old, New, sl, Type) \
764 SockList_AddChar(sl, Type); \
765 SockList_AddInt(sl, New); \
768 #define AddIfShort(Old, New, sl, Type) \
771 SockList_AddChar(sl, Type); \
772 SockList_AddShort(sl, New); \
775 #define AddIfFloat(Old, New, sl, Type) \
778 SockList_AddChar(sl, Type); \
779 SockList_AddInt(sl, (long)(New*FLOAT_MULTI));\
782 #define AddIfString(Old, New, sl, Type) \
783 if (Old == NULL || strcmp(Old, New)) { \
785 Old = strdup_local(New); \
786 SockList_AddChar(sl, Type); \
787 SockList_AddLen8Data(sl, New, strlen(New)); \
797 for (int16_t i = 1; i < until; i++) {
812 const char *god =
"none";
826 if (QUERY_FLAG(pl->ob, F)) { \
839 if (strcmp(item->arch->name,
"poisoning") == 0) {
842 if (strcmp(item->arch->name,
"blindness") == 0) {
845 if (item->type ==
FORCE && strcmp(item->name,
"confusion") == 0) {
848 if (item->type ==
SKILL && item->subtype ==
SK_PRAYING && item->title) {
875 if (pl->
ob != NULL) {
891 int16_t golem_hp, golem_maxhp;
899 if (pl->
ob != NULL) {
938 LOG(
llevDebug,
"pruning removed object from last_skill_ob\n");
1077 #define MAX_HEAD_POS MAX(MAX_CLIENT_X, MAX_CLIENT_Y)
1114 uint8_t nlayer, smoothlevel = 0;
1144 if (bx < ax || by < ay) {
1145 LOG(
llevError,
"map2_add_ob: bx (%d) or by (%d) is less than ax (%d) or ay (%d)\n", bx, by, ax, ay);
1152 for (l = layer-1; l <= layer+1; l++) {
1155 if (
heads[by][bx][l] == head)
1162 if (!
heads[by][bx][layer])
1163 heads[by][bx][layer] = head;
1165 heads[by][bx][layer+1] = head;
1170 uint16_t face_num =
face ?
face->number : 0;
1186 uint8_t len, anim_speed = 0, i;
1215 anim_speed = (int)(1.0/
FABS(ob->
speed));
1263 nlayer = 0x10+layer+(2<<5);
1284 int got_one = 0, poisoned = 0, diseased = 0;
1286 int value, granularity;
1287 const object *
probe;
1309 granularity = (
probe->level - 14) / 3;
1310 if (granularity <= 0)
1312 else if (granularity > 30)
1321 else if (value > granularity)
1322 value = granularity;
1326 value = (value * 30) / granularity;
1336 snprintf(
name,
sizeof(
name),
"hpbar%s%s%s_%d",
1337 poisoned ?
"_poisoned" :
"",
1338 diseased ?
"_diseased" :
"",
1339 (!poisoned && !diseased) ?
"_standard" :
"",
1342 if (dummy != NULL) {
1356 int len = strlen(label);
1357 if (len > 256 - 2 - 1) {
1358 LOG(
llevError,
"The label '%s' is too long to send to the client.", label);
1370 int got_one =
check_probe(ax, ay, ob, sl, ns, has_obj, alive_layer);
1375 if (dummy != NULL) {
1386 }
else if (plyr->
party) {
1413 int layer, got_one = 0, del_one = 0, oldlen, has_obj = 0;
1420 for (layer = 0; layer <
MAP_LAYERS; layer++) {
1423 head =
heads[ay][ax][layer];
1428 got_one +=
map2_add_ob(ax, ay, layer, head, sl, ns, &has_obj, 1);
1441 if (!del_one && !got_one) {
1443 }
else if (del_one && !has_obj) {
1460 int x, y, ax, ay, darkness, min_x, max_x, min_y, max_y, oldlen, layer;
1490 for (y = min_y; y < max_y; y++, ay++) {
1492 for (x = min_x; x < max_x; x++, ax++) {
1542 int have_darkness = 0, has_obj = 0, got_one = 0, del_one = 0, g1, alive_layer = -1, old_got;
1578 for (layer = 0; layer <
MAP_LAYERS; layer++) {
1595 if (got_one != old_got || ob->
head == NULL)
1596 got_one +=
annotate_ob(ax, ay, ob, &sl, plyr, &has_obj, &alive_layer);
1603 if (g1 == has_obj) {
1607 if (layer != alive_layer)
1614 if (!del_one && !got_one && !have_darkness) {
1616 }
else if (del_one && !has_obj) {
1638 if (sl.
len > startlen) {
1652 int min_x, min_y, max_x, max_y;
1655 LOG(
llevError,
"draw_client_map called with non player/non eric-server\n");
1679 for (j = min_y; j < max_y; j++) {
1680 for (i = min_x; i < max_x; i++) {
1724 for (x = 0; x < mx; x++) {
1725 for (y = 0; y < my; y++) {
1726 if (x >= ns->
mapx || y >= ns->
mapy) {
1728 memset(&newmap.
cells[x][y], 0,
sizeof(newmap.
cells[x][y]));
1729 }
else if (x+dx < 0 || x+dx >= ns->
mapx || y+dy < 0 || y+dy >= ns->
mapy) {
1731 memset(&newmap.
cells[x][y], 0,
sizeof(newmap.
cells[x][y]));
1856 switch (
spell->subtype)
1862 if (!
spell->other_arch)
1869 if (
spell->randomitems != NULL)
1881 int len, i,
skill = 0;
1921 len = strlen(
spell->msg);
1955 LOG(
llevError,
"esrv_add_spells, tried to add a spell to a NULL player\n");
1982 size += 2 + (value ? strlen(value) : 0);
1992 LOG(
llevError,
"Asked to send a non-spell object as a spell\n");
2079 uint16_t faceno = 0;
2090 if (acn->face[0] != 0 ) {
2097 faceno =
face->number;
2157 nlen = (
unsigned char)
buf[0];
2158 if (nlen >=
MAX_BUF || nlen > *len-2) {
2164 plen = (
unsigned char)
buf[nlen+1];
2165 if (plen >=
MAX_BUF || plen > *len-2-nlen) {
2168 memcpy(password,
buf+2+nlen, plen);
2190 if (len <= 0 || !
buf) {
2191 LOG(
llevDebug,
"IP '%s' sent bogus add_player_cmd information\n", ns->
host);
2213 SockList_AddString(&sl,
"failure accountlogin No such account name exists on this server");
2289 if (len <= 0 || !
buf) {
2290 LOG(
llevDebug,
"IP '%s' sent bogus add_player_cmd information\n", ns->
host);
2328 if (strlen(password)<2) {
2336 SockList_AddString(&sl,
"failure accountnew That account already exists on this server");
2345 "failure accountnew Choose a different account name. " VALIDCHAR_MSG);
2353 "failure accountnew That account name is too long");
2362 "failure accountnew Choose a different password. " VALIDCHAR_MSG);
2370 "failure accountnew That password is too long");
2400 int status, force, nlen;
2404 if (len <= 0 || !
buf) {
2405 LOG(
llevDebug,
"IP '%s' sent bogus add_player_cmd information\n", ns->
host);
2457 SockList_AddString(&sl,
"failure accountaddplayer 0 That character is already connected to this account.");
2463 SockList_AddString(&sl,
"failure accountaddplayer 1 That character is already connected to a different account.");
2475 SockList_AddString(&sl,
"failure accountaddplayer 0 That character is already connected to a different account which is currently logged in.");
2497 }
else if (status == 2) {
2498 SockList_AddString(&sl,
"failure accountaddplayer 0 You have reached the maximum number of characters allowed per account.");
2534 if (len <= 0 || !
buf) {
2535 LOG(
llevDebug,
"IP '%s' sent bogus account_play_cmd information\n", ns->
host);
2565 for (i=0; chars[i]; i++) {
2566 if (strcmp(chars[i],
buf) == 0)
2571 "failure accountplay Character %s is not associated with account %s",
2581 "failure accountplay Character %s is already playing",
2625 #define MAX_CHOICES 100
2635 int status, nlen, choice_num=0, i;
2638 archetype *map=NULL, *race_a=NULL, *class_a=NULL;
2641 if (len <= 0 || !
buf) {
2642 LOG(
llevDebug,
"IP '%s' sent bogus create_player_cmd information\n", ns->
host);
2673 SockList_AddString(&sl,
"failure createplayer Player name contains invalid characters");
2680 if (strlen(password)<2) {
2703 if (strlen(password)>17)
2774 int i, j, stat_total=0;
2775 char *key, *value, *race=NULL, *class_name=NULL;
2780 memset(&new_stats, 0,
sizeof(
living));
2782 while (nlen < len) {
2791 if ((i == 0) || (nlen + i > len))
break;
2799 key =
buf + nlen + 1;
2800 value = strchr(key,
' ');
2806 else if (!
strcasecmp(key,
"class")) class_name = value;
2811 "failure createplayer Invalid starting map");
2825 "Number of choices receive exceed max value: %d>%d\n",
2828 choices[choice_num] = value;
2836 int val = atoi(value);
2846 LOG(
llevError,
"Got unknown key/value from client: %s %s\n", key, value);
2864 "failure createplayer Stat value is out of range - %d must be between %d and %d",
2873 "failure createplayer Total allocated statistics is higher than allowed (%d>%d)",
2889 if (!race_a || race_a->clone.type !=
PLAYER || !class_a || class_a->clone.type !=
CLASS) {
2891 "failure createplayer Invalid or unknown race or class");
2902 "failure createplayer Unable to apply race or class - statistic is out of bounds");
2964 if (pl->
ob->
map == NULL) {
2984 for (i=0; i < choice_num; i++) {
2986 const char *value, *cp;
2990 choiceval = strchr(choices[i],
' ');
2992 LOG(
llevError,
"Choice does not specify value: %s\n", choices[i]);
3002 LOG(
llevError,
"Choice not found in archetype: %s\n", choices[i]);
3005 cp = strstr(value, choiceval);
3007 LOG(
llevError,
"Choice value not found in archetype: %s %s\n",
3008 choices[i], choiceval);
3018 if ((cp[strlen(choiceval)] !=
' ') && (cp[strlen(choiceval)] != 0) &&
3019 (cp != value) && (*(cp-1) !=
' ')) {
3021 LOG(
llevError,
"Choice value matches substring but not entire word: %s substring %s\n",
3027 LOG(
llevError,
"Choice value can not find archetype %s\n", choiceval);
3039 "%s has entered the game.", pl->
ob->
name);
3057 if (len <= 0 || !
buf) {
3058 LOG(
llevDebug,
"IP '%s' sent bogus account_password_cmd information\n", ns->
host);
3088 if (strlen(change)<2) {
3098 "failure accountpw Choose a different password. " VALIDCHAR_MSG);
3106 "failure accountpw That password is too long");
3117 error =
"failure accountpw Illegal characters present";
3118 }
else if (status == 2) {
3119 error =
"failure accountpw Invalid account";
3121 error =
"failure accountpw Incorrect current password";
player * find_player_socket(const socket_struct *ns)
Return a player for a socket structure.
#define ADD_PLAYER_NO_STATS_ROLL
Stats provided from client.
void account_add_player_cmd(char *buf, int len, socket_struct *ns)
Handle accountaddplayer from server (add a character to this account).
@ CLASS
Object for applying character class modifications to someone.
sstring name_pl
The plural name of the object.
#define CS_STAT_RES_DEPLETE
New face structure - this enforces the notion that data is face by face only - you can not change the...
uint32_t do_los
If true, need to call update_los() in draw(), and clear.
int16_t bed_y
x,y - coordinates of respawn (savebed).
#define MAP_CLIENT_X
This determines the maximum map size the client can request (and thus what the server will send to th...
#define CF_STEALTHY
Player is stealthy.
uint32_t tick
Client wishes to get tick commands.
static const short atnr_cs_stat[NROFATTACKS]
This table translates the attack numbers as used within the program to the value we use when sending ...
#define MAP_CLIENT_X_MINIMUM
player * next
Pointer to next player, NULL if this is last.
void SockList_AddInt(SockList *sl, uint32_t data)
Adds a 32 bit value.
#define NS_FACESENT_FACE
Bitmask for the faces_sent[] array - what portion of the face have we sent?
uint32_t sc_version
Versions of the client.
player * first_player
First player.
#define ST_CHANGE_PASSWORD_OLD
Player is entering old password to change password.
struct Settings settings
Server settings.
void print_ext_msg(socket_struct *ns, int color, uint8_t type, uint8_t subtype, const char *message)
Draws an extended message on the client.
int find_smooth(const Face *face, const Face **smoothed)
Find the smooth face for a given face.
int16_t maxhp
Max hit points.
bool heartbeat
Client will send hearbeats.
void SockList_AddInt64(SockList *sl, uint64_t data)
Adds a 64 bit value.
#define ST_GET_PASSWORD
Name entered, now for password.
#define FLAG_CONFUSED
Will also be unable to cast spells.
static bool CAN_PROBE(const object *ob)
Determine whether the given object can have an HP bar.
@ llevError
Error, serious thing.
#define FABS(x)
Decstations have trouble with fabs()...
#define FLAG_CLIENT_ANIM_RANDOM
Client animate this, randomized.
void send_account_players(socket_struct *ns)
Upon successful login/account creation, we send a list of characters associated with the account to t...
uint32_t path_attuned
Paths the object is attuned to.
#define CS_STAT_APPLIED_WIS
WIS changes from gear or skills.
static const int MAP2_COORD_MAX
int ssop_t
Parameter type for setsockopt, different between WIN32 and Linux.
#define MSG_TYPE_ADMIN_PLAYER
Player coming/going/death.
uint32_t mode
Mode of player for pickup.
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
void send_query(socket_struct *ns, uint8_t flags, const char *text)
Asks the client to query the user.
void account_play_cmd(char *buf, int len, socket_struct *ns)
We have received an accountplay command.
int16_t last_golem_hp
Last golem hp value sent to the client.
void new_player_cmd(uint8_t *buf, int len, player *pl)
This handles the commands issued by the player (ie, north, fire, cast, etc.).
This stores, for a spell a player knows, the last sp/gr/dam information sent to client.
#define MAP2_COORD_OFFSET
How much the x,y coordinates in the map2 are off from actual upper left corner.
uint32_t golem_count
To track the golem.
#define FLAG_STARTEQUIP
Object was given to player at start.
void ask_smooth_cmd(char *buf, int len, socket_struct *ns)
Tells client the picture it has to use to smooth a picture number given as argument.
#define QUERY_FLAG(xyz, p)
char const * newhash(char const *password)
uint32_t sound
Client sound mode.
same as sound ncom command like but with extra the client want tick commands so it knows animation timing the client wants to be informed of pickup mode changes Mode will be sent when the player successfully logs and afterward any time the value is but over many options have become defaults This documents those now obsolete client can handle the bit exp values that are now used values are sent as bit Setting this flag also means that skill exp will be and it will be sent in revised method as described in the stats command Value is an integer in string format else Deprecated client should presume all servers support this server will return FALSE Deprecated replaced with sound2 setup command
linked_char * account_get_additional_chars(const char *account_name, const Account_Chars *chars, int *count)
Get a list of character names linked to the specified account which are not listed in chars.
#define CS_STAT_APPLIED_POW
POW changes from gear or skills.
Socket structure, represents a client-server connection.
client_spell * spell_state
Spell information sent to client.
int get_skill_client_code(const char *skill_name)
Return the code of the skill for a client, the index in the skill_names array.
#define ST_GET_NAME
Player just connected.
static int map2_delete_layer(int ax, int ay, int layer, SockList *sl, socket_struct *ns)
void update_position(mapstruct *m, int x, int y)
This function updates various attributes about a specific space on the map (what it looks like,...
#define MAX_NUM_LOOK_OBJECTS
The upper bound for the number of objects to send for the 'look' window (container or ground view).
static const int MAP2_COORD_MIN
uint8_t num_look_objects
The maximum number of objects to show on the ground view; this number includes the prev/next group fa...
struct archetype * arch
Pointer to archetype.
void command_execute(object *pl, char *command)
Handle a player-issued command.
#define AddIfInt64(Old, New, sl, Type)
void SockList_AddString(SockList *sl, const char *data)
Adds a string without length.
float speed
Frequency of object 'moves' relative to server tick rate.
#define MAX_TIME
If you feel the game is too fast or too slow, change MAX_TIME.
#define CS_STAT_SPELL_DENY
char ** account_get_players_for_account(const char *account_name)
Returns an array of strings for the characters on this account - the array is null terminated.
int16_t invisible
How much longer the object will be invis.
void accounts_save(void)
Save all the account information.
uint32_t peaceful
If set, won't attack friendly creatures.
object * ob
The object representing the player.
object * transport
Transport the player is in.
void reply_cmd(char *buf, int len, player *pl)
This is a reply to a previous query.
float speed_left
How much speed is left to spend this round.
struct mapstruct * map
Pointer to the map in which this object is present.
uint32_t extended_stats
Client wants base and maximum statistics information.
static void append_spell(player *pl, SockList *sl, object *spell)
appends the spell *spell to the Socklist we will send the data to.
living last_applied_stats
Last applied stats sent to the client.
uint8_t min_name
Minimum characters for an account or player name.
int8_t levhp[11]
What hp bonus the player gained on that level.
non standard information is not specified or uptime this means how long since the executable has been started A particular host may have been running a server for quite a long time
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...) PRINTF_ARGS(6
uint32_t last_path_denied
Last spell denied sent to client.
uint8_t starting_stat_min
Minimum value of a starting stat.
@ SKILL
Also see SKILL_TOOL (74) below.
int16_t last_sp
Last spell cost.
uint32_t is_bot
Client shouldn't be reported to metaserver.
player * get_player(player *p)
Create a player's object, initialize a player's structure.
static void send_extra_stats(SockList *sl, player *pl)
Send extra stats for the player, if 'notification' is 3.
tag_t count
Unique object number for this object.
static const flag_definition flags[]
Flag mapping.
int8_t last_level
Last level we sent to client.
uint8_t smoothlevel
how to smooth this square around
int8_t levsp[11]
What sp bonus the player gained on that level.
#define CS_STAT_RES_HOLYWORD
static int annotate_ob(int ax, int ay, const object *ob, SockList *sl, player *plyr, int *has_obj, int *alive_layer)
char savebed_map[MAX_BUF]
Map where player will respawn after death.
#define CS_STAT_GOLEM_HP
Golem's current hp, 0 if no golem.
#define MAX_HEAD_OFFSET
This basically defines the largest size an archetype may be - it is used for allocation of some struc...
living last_stats
Last stats as sent to client.
int account_link(const char *account_name, const char *player_name)
Adds a player name to an account.
SockList inbuf
If we get an incomplete packet, this is used to hold the data.
#define CS_STAT_TURN_UNDEAD
#define SP_CREATE_MISSILE
#define CF_NOT_PERFECT
Can drink some improvement potions.
void receive_play_again(object *op, char key)
Player replied to play again / disconnect.
void set_player_socket(player *p, socket_struct *ns)
This copies the data from the socket into the player structure.
#define MSG_TYPE_COMMAND_ERROR
Bad syntax/can't use command.
static void map_clearcell(struct map_cell_struct *cell, int face, int darkness)
Clears a map cell.
static bool map2_coord_valid(int x)
#define FLAG_PROBE
Object displays HP information to player.
@ range_golem
Control golem.
void send_plugin_custom_message(object *pl, char *buf)
GROS: The following one is used to allow a plugin to send a generic cmd to a player.
void SockList_Reset(SockList *sl)
Resets the length of the stored data for writing.
#define CS_STAT_CHARACTER_FLAGS
Character flags, like 'confused' and such.
char path[HUGE_BUF]
Filename of the map.
const char * object_get_value(const object *op, const char *const key)
Get an extra value by key.
void set_up_cmd(char *buf, int len, socket_struct *ns)
This is the Setup cmd - easy first implementation.
#define UPD_SP_MANA
updspell command flag value.
int16_t level
Level of creature or object.
#define FLAG_STEALTH
Will wake monsters with less range.
map2_label
Map label subtypes.
living applied_stats
Stat changes due to gear or skills.
static const object * heads[MAX_HEAD_POS][MAX_HEAD_POS][MAP_LAYERS]
Using a global really isn't a good approach, but saves the over head of allocating and deallocating s...
uint32_t pticks
Number of ticks since time reset.
void key_confirm_quit(object *op, char key)
We receive the reply to the 'quit confirmation' message.
#define CS_STAT_APPLIED_DEX
DEX changes from gear or skills.
player * add_player(socket_struct *ns, int flags)
Tries to add player on the connection passwd in ns.
object * object_insert_in_ob(object *op, object *where)
This function inserts the object op in the linked list inside the object environment.
static void map2_add_label(socket_struct *ns, SockList *sl, enum map2_label subtype, const char *label)
#define MSG_TYPE_COMMAND
Responses to commands, eg, who.
int16_t resist[NROFATTACKS]
Resistance adjustments for attacks.
#define CS_STAT_GOLEM_MAXHP
Golem's max hp, 0 if no golem.
#define SND_EFFECTS
Those flags are for the 'socket.sound' field.
@ MAP2_LABEL_PLAYER_PARTY
Plugin animator file specs[Config] name
std::vector< Account_Char * > chars
Characters of the account.
#define FLAG_ALIVE
Object can fight (or be fought)
uint32_t path_denied
Paths the object is denied access to.
uint32_t update_look
If true, we need to send the look window.
size_t SockList_Avail(const SockList *sl)
Returns the available bytes in a SockList instance.
short GetShort_String(const unsigned char *data)
const char *const short_stat_name[NUM_STATS]
Short name of stats.
#define SP_SUMMON_MONSTER
#define UPD_SP_DAMAGE
updspell command flag value.
int16_t y
Position in the map for this object.
uint32_t path_repelled
Paths the object is repelled from.
static event_registration m
#define AddIfShort(Old, New, sl, Type)
Account_Chars * account_chars
Detailed information on characters on this account.
void esrv_send_animation(socket_struct *ns, const Animations *anim)
Need to send an animation sequence to the client.
uint8_t mapy
How large a map the client wants.
#define MAP_IN_MEMORY
Map is fully loaded.
struct player * contr
Pointer to the player which control this object.
void set_title(const object *pl, char *buf, size_t len)
Sets player title.
static int clamp(int x, int min, int max)
One map cell, as sent to the client.
#define CS_STAT_SPELL_REPEL
#define P_NEW_MAP
Coordinates passed result in a new tiled map.
uint8_t subtype
Subtype of object.
float last_speed
Last speed as sent to client.
uint32_t run_on
Player should keep moving in dir until run is off.
void account_new_cmd(char *buf, int len, socket_struct *ns)
Handles the account creation This function shares a fair amount of the same logic as account_login_cm...
uint8_t anim_speed
Ticks between animation-frames.
void account_login_cmd(char *buf, int len, socket_struct *ns)
Handles the account login.
int playername_ok(const char *cp)
Is the player name valid.
void esrv_send_face(socket_struct *ns, const Face *face, int nocache)
Sends a face to a client if they are in pixmap mode, nothing gets sent in bitmap mode.
int16_t last_dam
Last damage.
#define CS_STAT_APPLIED_CHA
CHA changes from gear or skills.
#define ST_CHANGE_PASSWORD_CONFIRM
Player is confirming new password.
uint32_t facecache
If true, client is caching images.
int check_race_and_class(living *stats, archetype *race, archetype *opclass)
This checks to see if the race and class are legal.
int8_t blocked_los[MAP_CLIENT_X][MAP_CLIENT_Y]
Array showing what spaces the player can see.
void check_login(object *op, const char *password)
Actually login a player, load from disk and such.
float weapon_speed
The overall speed of this object.
uint16_t last_flags
Fire/run on flags for last tick.
const char * account_get_account_for_char(const char *charname)
This looks at all the accounts and sees if charname is associated with any of them.
uint8_t account_block_create
#define ST_PLAY_AGAIN
Player left through a bed of reality, and can login again.
#define CS_STAT_GOD_NAME
Name of the god the character worships.
uint16_t number
This is the image unique identifier.
object * ranges[range_size]
Object for each range.
#define ADD_PLAYER_NO_MAP
Do not set the first map.
int darkness
Cell's darkness.
void account_char_free(Account_Chars *chars)
This frees all data associated with the character information.
object clone
An object from which to do object_copy()
static void send_smooth(socket_struct *ns, const Face *face)
A lot like the old AskSmooth (in fact, now called by AskSmooth).
static void handle_scroll(socket_struct *socket, SockList *sl)
As part of sending the map2 command, send one or more scroll commands to update the client map to mat...
sstring add_string(const char *str)
This will add 'str' to the hash table.
void draw_client_map(object *pl)
Draws client map.
int account_remove_player(const char *account_name, const char *player_name)
Removes a player name from an account.
sstring name
Usually monster-name/combination.
#define HEAD(op)
Returns the head part of an object.
void SockList_AddShort(SockList *sl, uint16_t data)
Adds a 16 bit value.
object * object_find_by_type_and_name(const object *who, int type, const char *name)
Find object in inventory by type and name.
void SockList_AddChar(SockList *sl, unsigned char c)
Adds an 8 bit value.
void set_attr_value(living *stats, int attr, int8_t value)
Sets Str/Dex/con/Wis/Cha/Int/Pow in stats to value, depending on what attr is (STR to POW).
#define FLAG_FREED
Object is in the list of free objects.
uint32_t last_path_attuned
Last spell attunment sent to client.
#define CF_POISONED
Poisoned.
const Face * face
Face with colors.
uint32_t last_character_flags
Last character flags (CS_STAT_CHARACTER_FLAGS) sent to client.
#define CS_STAT_APPLIED_STR
STR changes from gear or skills.
char * host
Which host it is connected from (ip address).
int64_t last_skill_exp[MAX_SKILLS]
Last exp sent to client.
void account_password(char *buf, int len, socket_struct *ns)
Handles the account password change.
void esrv_map_scroll(socket_struct *ns, int dx, int dy)
#define GET_MAP_FACE_OBJ(M, X, Y, L)
Gets the layer face of specified square.
char * account_name
Name of the account logged in on this socket.
int8_t levgrace[11]
What grace bonus the player gained on that level.
#define FREE_AND_COPY(sv, nv)
Release the shared string if not NULL, and make it a reference to nv.
int16_t last_grace
Last grace cost.
static void check_space_for_heads(int ax, int ay, SockList *sl, socket_struct *ns)
#define CS_STAT_OVERLOAD
How much (0 to 1) the character is overloaded.
uint8_t type
PLAYER, BULLET, etc.
int16_t dam
How much damage this object does when hitting.
uint32_t monitor_spells
Client wishes to be informed when their spell list changes.
#define FLAG_PARALYZED
Monster or player is paralyzed.
#define CS_STAT_APPLIED_CON
CON changes from gear or skills.
#define MAP_LAYER_LIVING1
Living creatures.
void esrv_update_spells(player *pl)
This looks for any spells the player may have that have changed their stats.
const char * skill_names[MAX_SKILLS]
Will contain a number-name mapping for skills, initialized by init_skills().
uint16_t faces[MAP_LAYERS]
Face numbers.
uint8_t faceset
Set the client is using, default 0.
with a maximum of six This is not so if you are wearing plate you receive no benefit Armour is additive with all the supplementry forms of which means that it lasts until the next semi permanent spell effect is cast upon the character spell
#define CS_STAT_RES_GHOSTHIT
struct linked_char * next
#define CS_STAT_SKILLINFO
CS_STAT_SKILLINFO is used as the starting index point.
#define FOR_INV_FINISH()
Finishes FOR_INV_PREPARE().
int account_new(const char *account_name, const char *account_password)
Adds an account.
#define ST_CHANGE_PASSWORD_NEW
Player is entering new password.
int16_t item_power
Total item power of objects equipped.
int32_t food
How much food in stomach.
#define CS_STAT_RES_BLIND
#define FLAG_UNAGGRESSIVE
Monster doesn't attack players.
#define CF_DISEASED
Has at least one disease.
#define MAP2_TYPE_DARKNESS
static uint16_t MAP2_COORD_ENCODE(int x, int y, int flags)
Encodes a (x, y) pair suitable for map2 parameters.
The archetype structure is a set of rules on how to generate and manipulate objects which point to ar...
int32_t last_weight_limit
Last weight limit transmitted to client.
#define SND_MUTE
Don't sent anything for now.
#define MAX_SKILLS
This is the maximum number of skills the game may handle.
mapstruct * get_map_from_coord(mapstruct *m, int16_t *x, int16_t *y)
This is basically the same as out_of_map above(), but instead we return NULL if no map is valid (coor...
const Face * get_face_by_id(uint16_t id)
Get a face from its unique identifier.
living last_race_stats
Last race stats sent to the client.
int16_t SP_level_spellpoint_cost(object *caster, object *spell, int flags)
Scales the spellpoint cost of a spell by it's increased effectiveness.
int account_is_logged_in(const char *name)
This checkes if an account is logged in.
const Animations * animation
Animation of this item, NULL if not animated.
uint32_t fire_on
Player should fire object, not move.
#define MAP_TYPE_CHOICE
Choice of maps presented to player.
void SockList_Init(SockList *sl)
Initializes the SockList instance.
static uint8_t is_perfect(const player *pl)
Check whether the player is perfect relatively to improvement potions.
TIPS on SURVIVING Crossfire is populated with a wealth of different monsters These monsters can have varying immunities and attack types In some of them can be quite a bit smarter than others It will be important for new players to learn the abilities of different monsters and learn just how much it will take to kill them This section discusses how monsters can interact with players Most monsters in the game are out to mindlessly kill and destroy the players These monsters will help boost a player s after he kills them When fighting a large amount of monsters in a single attempt to find a narrower hallway so that you are not being attacked from all sides Charging into a room full of Beholders for instance would not be open the door and fight them one at a time For there are several maps designed for them Find these areas and clear them out All throughout these a player can find signs and books which they can read by stepping onto them and hitting A to apply the book sign These messages will help the player to learn the system One more always keep an eye on your food If your food drops to your character will soon so BE CAREFUL ! NPCs Non Player Character are special monsters which have intelligence Players may be able to interact with these monsters to help solve puzzles and find items of interest To speak with a monster you suspect to be a simply move to an adjacent square to them and push the double ie Enter your and press< Return > You can also use say if you feel like typing a little extra Other NPCs may not speak to but display intelligence with their movement Some monsters can be and may attack the nearest of your enemies Others can be in that they follow you around and help you in your quest to kill enemies and find treasure SPECIAL ITEMS There are many special items which can be found in of these the most important may be the signs all a player must do is apply the handle In the case of the player must move items over the button to hold it down Some of the larger buttons may need very large items to be moved onto before they can be activated Gates and locked but be for you could fall down into a pit full of ghosts or dragons and not be able to get back out Break away sometimes it may be worth a player s time to test the walls of a map for secret doors Fire such as missile weapons and spells you will notice them going up in smoke ! So be careful not to destroy valuable items Spellbooks sometimes a player can learn the other times they cannot There are many different types of books and scrolls out there Improve item have lower weight
uint16_t last_item_power
Last value for item_power.
uint8_t num_animations
How many different faces to animate, size of the faces array.
Various statistics of objects.
object * last_skill_ob[MAX_SKILLS]
Exp objects sent to client.
#define P_OUT_OF_MAP
This space is outside the map.
#define CS_STAT_WEIGHT_LIM
#define MAX_BUF
Used for all kinds of things.
int32_t last_weight
Last weight as sent to client; -1 means do not send weight.
#define CS_STAT_ITEM_POWER
Equipped item power.
#define CS_STAT_RES_POISON
void receive_player_name(object *op, const char *name)
A player just entered her name.
int is_valid_faceset(int fsn)
Checks specified faceset is valid.
object * head
Points to the main object of a large body.
#define ADD_PLAYER_NEW
Name/password provided, so skip to roll stats.
living orig_stats
Permanent real stats of player.
object * object_present_in_ob(uint8_t type, const object *op)
Searches for any objects with a matching type variable in the inventory of the given object.
uint32_t get_weight_limit(int stat)
int8_t wc
Weapon Class, lower WC increases probability of hitting.
void SockList_Term(SockList *sl)
Frees all resources allocated by a SockList instance.
int16_t last_golem_maxhp
Last golem max hp value sent to the client.
#define AddIfInt(Old, New, sl, Type)
int probe(object *op, object *caster, object *spell_ob, int dir, int level)
Try to get information about a living thing.
#define FLAG_CLIENT_SENT
We use it to detect cases were the server is trying to send an upditem when we have not actually sent...
void key_roll_stat(object *op, char key)
Player is currently swapping stats.
int16_t maxgrace
Maximum grace.
#define FLAG_CLIENT_ANIM_SYNC
Let client animate this, synchronized.
uint8_t starting_stat_points
How many stat points character starts with.
#define ST_PLAYING
Usual state.
void create_player_cmd(char *buf, int len, socket_struct *ns)
We have received a createplayer command.
int apply_race_and_class(object *op, archetype *race, archetype *opclass, living *stats)
This is somewhat like key_change_class() above, except we know the race to change to,...
#define FLAG_REMOVED
Object is not in any map or invenory.
#define ST_CHANGE_CLASS
New character, choosing class.
#define CS_STAT_SPELL_ATTUNE
#define FLAG_WIZ
Object has special privilegies.
void SockList_AddData(SockList *sl, const void *data, size_t len)
Adds a data block.
#define NDI_UNIQUE
Print immediately, don't buffer.
void esrv_move_object(object *pl, tag_t to, tag_t tag, long nrof)
Move an object to a new location.
const Face ** faces
The actual faces for the animation.
#define FLAG_FRIENDLY
Will help players.
client_spell * get_client_spell_state(player *pl, object *spell)
Gets the (client-side) spell state for specified spell.
sstring name
The name of the object, obviously...
int SP_level_dam_adjust(const object *caster, const object *spob)
Returns adjusted damage based on the caster.
uint32_t want_pickup
Client wants pickup information when logging in.
object * object_find_by_arch_name(const object *who, const char *name)
Find object in inventory by archetype name.
#define AddIfFloat(Old, New, sl, Type)
#define ST_CONFIRM_PASSWORD
New character, confirm password.
void send_tick(player *pl)
static int map2_add_ob(int ax, int ay, int layer, const object *ob, SockList *sl, socket_struct *ns, int *has_obj, int is_head)
object 'ob' at 'ax,ay' on 'layer' is visible to the client.
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
This rolls up wall, blocks_magic, blocks_view, etc, all into one function that just returns a P_.
static int account_block_create(const socket_struct *ns)
Checks if account creation is blocked for this connection.
int16_t maxsp
Max spell points.
#define P_NEED_UPDATE
This space is out of date.
void enter_exit(object *op, object *exit_ob)
Tries to move 'op' to exit_ob.
#define BEAT_INTERVAL
Interval between heartbeat requests.
void map_newmap_cmd(socket_struct *ns)
Sound related function.
void esrv_add_spells(player *pl, object *spell)
This tells the client to add the spell *spell, if spell is NULL, then add all spells in the player's ...
#define SND_MUSIC
Client wants background music info.
const typedef char * sstring
#define NDI_ALL
Inform all players of this message.
This represents one animation.
#define MAP_CLIENT_Y_MINIMUM
#define FLAG_AUTO_APPLY
Will be applied when created.
uint8_t state
Input state of the player (name, password, etc).
void esrv_remove_spell(player *pl, object *spell)
void SockList_AddLen8Data(SockList *sl, const void *data, size_t len)
Adds a data block prepended with an 8 bit length field.
void receive_player_password(object *op, const char *password)
A player just entered her password, including for changing it.
uint32_t in_memory
Combination of IN_MEMORY_xxx flags.
void add_me_cmd(char *buf, int len, socket_struct *ns)
The client has requested to be added to the game.
void esrv_draw_look(object *pl)
Send the look window.
sstring msg
If this is a book/sign/magic mouth/etc.
void version_cmd(char *buf, int len, socket_struct *ns)
Client tells its version.
struct map_cell_struct cells[MAX_CLIENT_X][MAX_CLIENT_Y]
#define CF_CONFUSED
Confused by a spell or an item.
method_ret ob_apply(object *op, object *applier, int aflags)
Apply an object by running an event hook or an object method.
uint16_t num
Where we are in the array.
int8_t ac
Armor Class, lower AC increases probability of not getting hit.
#define NUM_ANIMATIONS(ob)
void SockList_ResetRead(SockList *sl)
Resets the length of the stored data for reading.
#define NDI_DK_ORANGE
DarkOrange2.
uint8_t anims_sent[MAXANIMNUM]
What animations we sent.
living last_orig_stats
Last permanent stats sent to client.
int account_change_password(const char *account_name, const char *current_password, const char *new_password)
Change an account password.
uint8_t * faces_sent
This is a bitmap on sent face status.
int16_t last_resist[NROFATTACKS]
last resist values sent to client.
#define CS_STAT_RES_DEATH
object * arch_to_object(archetype *at)
Creates and returns a new object which is a copy of the given archetype.
partylist * party
Party this player is part of.
====Textual A command containing textual data has data fields separated by one ASCII space character. word::A sequence of ASCII characters that does not contain the space or nul character. This is to distinguish it from the _string_, which may contain space characters. Not to be confused with a machine word. int::A _word_ containing the textual representation of an integer. Not to be confused with any of the binary integers in the following section. Otherwise known as the "string value of integer data". Must be parsed, e.g. using `atoi()` to get the actual integer value. string::A sequence of ASCII characters. This must only appear at the end of a command, since spaces are used to separate fields of a textual message.=====Binary All multi-byte integers are transmitted in network byte order(MSB first). int8::1-byte(8-bit) integer int16::2-byte(16-bit) integer int32::4-byte(32-bit) integer lstring::A length-prefixed string, which consists of an `int8` followed by that many bytes of the actual string. This is used to transmit a string(that may contain spaces) in the middle of binary data. l2string::Like _lstring_, but is prefixed with an `int16` to support longer strings Implementation Notes ~~~~~~~~~~~~~~~~~~~~ - Typical implementations read two bytes to determine the length of the subsequent read for the actual message, then read and parse the data from each message according to the commands described below. To send a message, the sender builds the message in a buffer, counts the length of the message, sends the length, and finally sends the actual message. TIP:Incorrectly transmitting or receiving the `length` field can lead to apparent "no response" issues as the client or server blocks to read the entire length of the message. - Since the protocol is highly interactive, it may be useful to set `TCP_NODELAY` on both the client and server. - If you are using a language with a buffered output stream, remember to flush the stream after a complete message. - If the connection is lost(which will also happen if the output buffer overflowing), the player is saved and the server cleans up. This does open up some abuses, but there is no perfect solution here. - The server only reads data from the socket if the player has an action. This isn 't really good, since many of the commands below might not be actual commands for the player. The alternative is to look at the data, and if it is a player command and there isn 't time, store it away to be processed later. But this increases complexity, in that the server must start buffering the commands. Fortunately, for now, there are few such client commands. Commands -------- In the documentation below, `S->C` represents a message to the client from the server, and `C->S` represents a message to the server from the client. Commands are documented in a brief format like:C->S:version< csval >[scval[vinfo]] Fields are enclosed like `< this >`. Optional fields are denoted like `[this]`. Spaces that appear in the command are literal, i.e. the<< _version > > command above uses spaces to separate its fields, but the command below does not:C->S:accountlogin< name >< password > As described in<< _messages > >, if a command contains data, then the command is separated from the data by a literal space. Many of the commands below refer to 'object tags'. Whenever the server creates an object, it creates a unique tag for that object(starting at 1 when the server is first run, and ever increasing.) Tags are unique, but are not consistent between runs. Thus, the client can not store tags when it exits and hope to re-use them when it joins the server at a later time - tags are only valid for the current connection. The protocol commands are broken into various sections which based somewhat on what the commands are for(ie, item related commands, map commands, image commands, etc.) In this way, all the commands related to similar functionality is in the same place. Initialization ~~~~~~~~~~~~~~ version ^^^^^^^ C->S:version< csval >[scval[vinfo]] S->C:version< csval >[scval[vinfo]] Used by the client and server to exchange which version of the Crossfire protocol they understand. Neither send this in response to the other - they should both send this shortly after a connection is established. csval::int, version level of C->S communications scval::int, version level of S->C communications vinfo::string, that is purely for informative that general client/server info(ie, javaclient, x11client, winclient, sinix server, etc). It is purely of interest of server admins who can see what type of clients people are using.=====Version ID If a new command is added to the protocol in the C->S direction, then the version number in csval will get increased. Likewise, the same is true for the scval. The version are currently integers, in the form ABCD. A=1, and will likely for quite a while. This will only really change if needed from rollover of B. B represents major protocol changes - if B mismatches, the clients will be totally unusable. Such an example would be change of map or item sending commands(either new commands or new format.) C represents more minor but still significant changes - clients might still work together, but some features that used to work may now fail due to the mismatch. An example may be a change in the meaning of some field in some command - providing the field is the same size, it still should be decoded properly, but the meaning won 't be processed properly. D represents very minor changes or new commands. Things should work no worse if D does not match, however if they do match, some new features might be included. An example of the would be the C->S mark command to mark items. Server not understanding this just means that the server can not process it, and will ignore it.=====Handling As far as the client is concerned, its _scval_ must be at least equal to the server, and its _csval_ should not be newer than the server. The server does not care about the version command it receives right now - all it currently does is log mismatches. In theory, the server should keep track of what the client has, and adjust the commands it sends respectively in the S->C direction. The server is resilant enough that it won 't crash with a version mismatch(however, client may end up sending commands that the server just ignores). It is really up to the client to enforce versioning and quit if the versions don 't match. NOTE:Since all packets have the length as the first 2 bytes, all that either the client or server needs to be able to do is look at the first string and see if it understands it. If not, it knows how many bytes it can skip. As such, exact version matches should not be necessary for proper operation - however, both the client and server needs to be coded to handle such cases.=====History _scval_ and _vinfo_ were added in version 1020. Before then, there was only one version sent in the version command. NOTE:For the most part, this has been obsoleted by the setup command which always return status and whether it understood the command or not. However there are still some cases where using this versioning is useful - an example it the addition of the requestinfo/replyinfo commands - the client wants to wait for acknowledge of all the replyinfo commands it has issued before sending the addme command. However, if the server doesn 't understand these options, the client will never get a response. With the versioning, the client can look at the version and know if it should wait for a response or if the server will never send back. setup ^^^^^ C->S, S->C:setup< option1 >< value1 >< option2 >< value2 > ... Sent by the client to request protocol option changes. This can be at any point during the life of a connection, but usually sent at least once right after the<< _version > > command. The server responds with a message in the same format confirming what configuration options were set. The server only sends a setup command in response to one from the client. The sc_version should be updated in the server if commands have been obsoleted such that old clients may not be able to play. option::word, name of configuration option value::word, value of configuration option. May need further parsing according to the setup options below=====Setup Options There are really 2 set of setup commands here:. Those that control preferences of the client(how big is the map, what faceset to use, etc). . Those that describe capabilities of the client(client supports this protocol command or that) .Setup Options[options="autowidth,header"]|===========================|Command|Description|beat|Ask the server to enable heartbeat support. When heartbeat is enabled, the client must send the server a command every three seconds. If no commands need to be sent, use the `beat` no-op command. Clients that do not contact the server within the interval are assumed to have a temporary connection failure.|bot(0/1 value)|If set to 1, the client will not be considered a player when updating information to the metaserver. This is to avoid having a server with many bots appear more crowded than others.|darkness(0/1 value)|If set to 1(default), the server will send darkness information in the map protocol commands. If 0, the server will not include darkness, thus saving a minor amount of bandwidth. Since the client is free to ignore the darkness information, this does not allow the client to cheat. In the case of the old 'map' protocol command, turning darkness off will result in the masking faces not getting sent to the client.|extended_stats(0/1 value)|If set to 1, the server will send the CS_STAT_RACE_xxx and CS_STAT_BASE_xxx values too, so the client can display various status related to statistics. Default is 0.|facecache(0/1)|Determines if the client is caching images(1) or wants the images sent to it without caching them(0). Default is 0. This replaces the setfacemode command.|faceset(8 bit)|Faceset the client wishes to use. If the faceset is not valid, the server returns the faceset the client will be using(default 0).|loginmethod(8 bit)|Client sends this to server to note login support. This is basically used as a subset of the csversion/scversion to find out what level of login support the server and client support. Current defined values:0:no advanced support - only legacy login method 1:account based login(described more below) 2:new character creation support This list may grow - for example, advanced character creation could become a feature.|map2cmd:(1)|This indicates client support for the map2 protocol command. See the map2 protocol details above for the main differences. Obsolete:This is the only supported mode now, but many clients use it as a sanity check for protocol versions, so the server still replies. It doesn 't do anything with the data|mapsize(int x) X(int y)|Sets the map size to x X y. Note the spaces here are only for clarity - there should be no spaces when actually sent(it should be 11x11 or 25x25). The default map size unless changed is 11x11. The minimum map size the server will allow is 9x9(no technical reason this could be smaller, but I don 't think the game would be smaller). The maximum map size supported in the current protocol is 63x63. However, each server can have its maximum map size sent to most any value. If the client sends an invalid mapsize command or a mapsize of 0x0, the server will respond with a mapsize that is the maximum size the server supports. Thus, if the client wants to know the maximum map size, it can just do a 'mapsize 0x0' or 'mapsize' and it will get the maximum size back. The server will constrain the provided mapsize x &y to the configured minumum and maximums. For example, if the maximum map size is 25x25, the minimum map size is 9x9, and the client sends a 31x7 mapsize request, the mapsize will be set to 25x9 and the server will send back a mapsize 25x9 setup command. When the values are valid, the server will send back a mapsize XxY setup command. Note that this is from its parsed values, so it may not match stringwise with what the client sent, but will match 0 wise. For example, the client may send a 'mapsize 025X025' command, in which case the server will respond with a 'mapsize 25x25' command - the data is functionally the same. The server will send an updated map view when this command is sent.|notifications(int value)|Value indicating what notifications the client accepts. It is incremental, a value means "all notifications till this level". The following levels are supported:1:quest-related notifications("addquest" and "updquest") 2:knowledge-related notifications("addknowledge") 3:character status flags(overloaded, blind,...)|num_look_objects(int value)|The maximum number of objects shown in the ground view. If more objects are present, fake objects are created for selecting the previous/next group of items. Defaults to 50 if not set. The server may adjust the given value to a suitable one data
int GetInt_String(const unsigned char *data)
Basically does the reverse of SockList_AddInt, but on strings instead.
static void draw_client_map2(object *pl)
uint32_t count
Any numbers typed before a command.
int strcasecmp(const char *s1, const char *s2)
#define MAP_LAYER_FLY2
Arrows, etc.
#define MAP_TYPE_DEFAULT
If no map is specified, where character starts.
int save_player(object *op, int flag)
Saves a player to disk.
#define ST_GET_PARTY_PASSWORD
Player tried to join a password-protected party.
#define VERSION_CS
Version >= 1023 understand setup cmd.
Structure handling character information for an account.
#define UPD_SP_GRACE
updspell command flag value.
archetype * get_archetype_by_type_subtype(int type, int subtype)
Retrieves an archetype by type and subtype.
#define CF_WIZARD
Player is DM.
float character_load
Value between 0 and 1 indicating how much the character is overloaded.
void esrv_send_pickup(player *pl)
Sends the "pickup" state to pl if client wants it requested.
void object_remove(object *op)
This function removes the object op from the linked list of objects which it is currently tied to.
void player_set_state(player *pl, uint8_t state)
Set the player's state to the specified one.
void free_charlinks(linked_char *lc)
Frees a link structure and its next items.
archetype * try_find_archetype(const char *name)
#define AddIfString(Old, New, sl, Type)
const Face * try_find_face(const char *name, const Face *error)
same as sound ncom command like but with extra the client want tick commands so it knows animation timing want_pickup(0/1)|If set
uint32_t last_path_repelled
Last spell repelled sent to client.
#define MIN_NUM_LOOK_OBJECTS
The lower bound for the number of objects to send for the 'look' window (container or ground view).
#define MAP_LAYER_LIVING2
uint8_t login_method
Login method this client is using.
int8_t tail_y
Where the lower right most portion of the object is in comparison to the head.
static int check_probe(int ax, int ay, const object *ob, SockList *sl, socket_struct *ns, int *has_obj, int *alive_layer)
Check if a hp bar should be added to the map square.
#define ST_CONFIRM_QUIT
Player used the 'quit' command, make sure that's ok.
char password[16]
2 (seed) + 11 (crypted) + 1 (EOS) + 2 (safety) = 16
void move_cmd(char *buf, int len, player *pl)
Moves an object (typically, container to inventory).
Account_Chars * account_char_load(const char *account_name)
For a given account name, load the character information and return it.
void key_change_class(object *op, char key)
This function takes the key that is passed, and does the appropriate action with it (change race,...
void receive_party_password(object *op, const char *password)
Player entered a party password.
static int spell_client_use(const object *spell)
Give the client-side use information for a spell, to know how to use a spell.
sstring name
More definite name, like "generate_kobold".
int account_check_string(const char *str)
Checks a string to make sure it does not have any invalid characters.
void esrv_update_stats(player *pl)
Sends a statistics update.
uint32_t darkness
True if client wants darkness information.
#define FLAG_XRAYS
X-ray vision.
socket_struct * socket
Socket information for this player.
uint16_t notifications
Notifications this client wants to get.
char * account_trusted_host
Block account creation for untrusted hosts.
living stats
Str, Con, Dex, etc.
#define MSG_TYPE_ADMIN_VERSION
version info
int8_t get_attr_value(const living *stats, int attr)
Gets the value of a stat.
void update_los(object *op)
Recalculates the array which specifies what is visible for the given player-object.
static void add_char_field(SockList *sl, int type, const char *data)
Basic helper function which adds a piece of data for the accountplayers protocol command.
int account_login(const char *account_name, const char *account_password)
Check if the given account exists, and whether the password is correct.
uint8_t always_show_hp
'probe' spell HP bars for all living things (0, 1, or 2)
float last_weapon_sp
if diff than weapon_sp, update client.
int verify_player(const char *name, char *password)
This verify that a character of name exits, and that it matches password.
#define ST_ROLL_STAT
New character, rolling stats.
void esrv_new_player(player *pl, uint32_t weight)
Tells the client that here is a player it should start using.
static int decode_name_password(const char *buf, int *len, char *name, char *password)
This is a basic routine which extracts the name/password from the buffer.
void account_char_save(Account_Chars *chars)
Saves the character information for the given account.
uint32_t name_changed
If true, the player has set a name.
#define CS_STAT_RES_DRAIN
void Send_With_Handling(socket_struct *ns, SockList *sl)
Calls Write_To_Socket to send data to the client.
#define CF_HOSTILE
'hostile' flag is set.
Contains the base information we use to make up a packet we want to send.
void map_reset_swap(mapstruct *m)
Call this when an in-memory map is used or referenced.
#define CF_PARALYZED
Player is paralyzed.
@ NUM_STATS
Number of statistics.
#define FOR_INV_PREPARE(op_, it_)
Constructs a loop iterating over the inventory of an object.
float last_character_load
Last value sent to the client.
void account_char_remove(Account_Chars *chars, const char *pl_name)
This removes a character on this account.
const char * NPC_DIALOG_ARCH
#define CS_STAT_APPLIED_INT
INT changes from gear or skills.
#define MAX_LIGHT_RADII
Max radii for 'light' object, really large values allow objects that can slow down the game.
#define CF_XRAY
Has X-ray.
void rangetostring(const object *pl, char *obuf, size_t len)
Get player's current range attack in obuf.
@ llevDebug
Only for debugging purposes.
#define NS_FACESENT_SMOOTH
void SockList_AddPrintf(SockList *sl, const char *format,...)
Adds a printf like formatted string.
const char * account_exists(const char *account_name)
Checks the existing accounts, and see if this account exists.
in that case they will be relative to whatever the PWD of the crossfire server process is You probably shouldn though Notes on Specific and settings file datadir Usually usr share crossfire Contains data that the server does not need to modify while such as the etc A default install will pack the and treasurelist definitions into a single or trs file and the graphics into a face(metadata) and .tar(bitmaps) file
uint8_t starting_stat_max
Maximum value of a starting stat.