Go to the documentation of this file.
76 #define ASSERT_LEN(function, curpos, buflen) \
77 if (curpos > buflen) { \
78 LOG(LOG_WARNING, function, "Data goes beyond length of buffer (%d>%d)", curpos, buflen); \
173 int pos, type, length, map_entry=-1;
188 if ((length+pos) > len) {
190 "Length of data is greater than buffer (%d>%d)", length + pos, len);
194 cp = g_malloc(length+1);
195 strncpy(cp, (
char *)data + pos, length);
213 "Could not allocate memory: %s", strerror(errno));
228 "Unknown type: %d\n", type);
275 "Length of line is greater than buffer (%d>%d)", llen, len);
282 while (olen <= len) {
283 if (!isspace(data[olen])) {
290 "Overran length of buffer (%d>%d)", olen, len);
294 cp = (
char *)data + olen;
296 while (olen <= len) {
297 if (isspace(data[olen])) {
306 "Overran length of buffer (%d>%d)", olen, len);
313 if (!g_ascii_strcasecmp(cp,
"points")) {
317 }
else if (!g_ascii_strcasecmp(cp,
"statrange")) {
320 "Unable to process statrange line (%s)", data + olen);
325 }
else if (!g_ascii_strcasecmp(cp,
"statname")) {
336 while (olen < llen) {
338 if (!g_ascii_strncasecmp((
char *)data + olen,
347 "Unable to find matching stat name (%s)", data + olen);
353 "Did not get correct number of stats (%d!=%d)", matches,
NUM_STATS);
357 }
else if (!g_ascii_strcasecmp(cp,
"race") || !g_ascii_strcasecmp(cp,
"class")) {
358 if (g_ascii_strcasecmp((
char *)data + olen,
"requestinfo")) {
360 "Got unexpected value for %s: %s", cp, data+olen);
364 }
else if (!g_ascii_strcasecmp(cp,
"startingmap")) {
365 if (g_ascii_strcasecmp((
char *)data + olen,
"requestinfo")) {
367 "Got unexpected value for %s: %s", cp, data+olen);
375 if (datatype ==
'V' || datatype ==
'R') {
377 "Got unsupported string from server, type %c, value %s", datatype, cp);
394 "Processed all newcharinfo yet have 0 value: stat_min=%d, stat_maximum=%d, stat_points=%d",
427 for (i=0; i<num_entries; i++) {
430 if (data[i].arch_name) {
431 free(data[i].arch_name);
433 if (data[i].public_name) {
434 free(data[i].public_name);
436 if (data[i].description) {
437 free(data[i].description);
444 free(data[i].rc_choice[j].value_arch[k]);
445 free(data[i].rc_choice[j].value_desc[k]);
447 free(data[i].rc_choice[j].value_arch);
448 free(data[i].rc_choice[j].value_desc);
449 free(data[i].rc_choice[j].choice_name);
450 free(data[i].rc_choice[j].choice_desc);
470 char *cp = (
char *)data, *nl;
475 nl = strchr(cp,
'\n');
481 LOG(
LOG_WARNING,
"common::process_race_class_info",
"Did not find archetype name");
490 nl = strchr(cp,
' ');
502 if (!strcmp(cp,
"name")) {
513 (
unsigned char *)nl + namelen, data + len);
519 }
else if (!strcmp(cp,
"stats")) {
524 while (cp < (
char *)data + len && *cp != 0) {
535 "Unknown stat value: %d", cp);
543 }
else if (!strcmp(cp,
"msg")) {
551 (
unsigned char *)nl + msglen, data + len);
557 }
else if (!strcmp(cp,
"choice")) {
571 (
unsigned char *)cp + clen, data + len);
581 (
unsigned char *)cp + clen, data + len);
604 (
unsigned char *)cp + clen, data + len);
613 (
unsigned char *)cp + clen, data + len);
624 LOG(
LOG_WARNING,
"common::process_race_class_info",
"Got unknown keyword: %s", cp);
627 }
while ((
unsigned char *)cp < data + len);
663 (
int (*)(
const void *,
const void *))
rc_compar);
694 (
int (*)(
const void *,
const void *))
rc_compar);
710 LOG(
LOG_ERROR,
"common::get_exp_info",
"no max level info from server provided");
717 for (level = 1; level <=
exp_table_max && pos < len; level++) {
723 "Incomplete table sent - got %d entries, wanted %d", level,
exp_table_max);
739 nl = strchr(cp,
'\n');
744 sn = strchr(cp,
':');
746 LOG(
LOG_WARNING,
"common::get_skill_info",
"corrupt line: /%s/", cp);
757 LOG(
LOG_WARNING,
"common::get_skill_info",
"invalid skill number %d", val);
764 }
while (cp < data+len);
785 for (i = 0; i < len; i++) {
787 if (*(buf+i) ==
' ' || *(buf+i) ==
'\n') {
797 LOG(
LOG_DEBUG,
"common::ReplyInfoCmd",
"Never found a space in the replyinfo");
804 if (!strcmp((
char*)buf,
"image_info")) {
806 }
else if (!strcmp((
char*)buf,
"image_sums")) {
808 }
else if (!strcmp((
char*)buf,
"skill_info")) {
810 }
else if (!strcmp((
char*)buf,
"exp_table")) {
812 }
else if (!strcmp((
char*)buf,
"motd")) {
816 motd = g_strdup((
char *)cp);
818 }
else if (!strcmp((
char*)buf,
"news")) {
822 news = g_strdup((
char *)cp);
824 }
else if (!strcmp((
char*)buf,
"rules")) {
828 rules = g_strdup((
char *)cp);
830 }
else if (!strcmp((
char*)buf,
"race_list")) {
832 for (cp1=cp; *cp !=0; cp++) {
856 }
else if (!strcmp((
char*)buf,
"class_list")) {
858 for (cp1=cp; *cp !=0; cp++) {
882 }
else if (!strcmp((
char*)buf,
"race_info")) {
884 }
else if (!strcmp((
char*)buf,
"class_info")) {
886 }
else if (!strcmp((
char*)buf,
"newcharinfo")) {
888 }
else if (!strcmp((
char*)buf,
"startingmap")) {
922 for (; buf[s] && buf[s] !=
' '; s++)
925 while (buf[s] ==
' ') {
934 for (; buf[s] && buf[s] !=
' '; s++)
937 while (s < len && buf[s] ==
' ') {
945 if (!strcmp(cmd,
"sound2")) {
949 }
else if (!strcmp(cmd,
"sound")) {
951 }
else if (!strcmp(cmd,
"mapsize")) {
952 if (!g_ascii_strcasecmp(param,
"false")) {
954 "Server only supports standard sized maps (11x11)");
967 for (
char *cp = param; *cp != 0; cp++) {
968 if (*cp ==
'x' || *cp ==
'X') {
988 snprintf(tmpbuf,
sizeof(tmpbuf),
"Server supports a max mapsize of %d x %d - requesting a %d x %d mapsize",
1002 snprintf(tmpbuf,
sizeof(tmpbuf),
"Unable to set mapsize on server - we wanted %d x %d, server returned %d x %d",
1006 }
else if (!strcmp(cmd,
"darkness")) {
1009 if (!strcmp(param,
"FALSE")) {
1010 LOG(
LOG_WARNING,
"common::SetupCmd",
"Server returned FALSE for setup command %s", cmd);
1012 }
else if (!strcmp(cmd,
"spellmon")) {
1033 if (!strcmp(param,
"FALSE")) {
1034 LOG(
LOG_INFO,
"common::SetupCmd",
"Server returned FALSE for a %s setup command", cmd);
1038 }
else if (!strcmp(cmd,
"facecache")) {
1040 }
else if (!strcmp(cmd,
"faceset")) {
1041 if (!strcmp(param,
"FALSE")) {
1043 "Server does not support other image sets, will use default");
1046 }
else if (!strcmp(cmd,
"map2cmd")) {
1047 if (!strcmp(param,
"FALSE")) {
1049 "Server does not support map2cmd!");
1051 "This server is too old to support this client!");
1054 }
else if (!strcmp(cmd,
"want_pickup")) {
1058 }
else if (!strcmp(cmd,
"loginmethod")) {
1059 int method = atoi(param);
1068 }
else if (!strcmp(cmd,
"newmapcmd")) {
1070 }
else if (!strcmp(cmd,
"tick")) {
1074 if (!strcmp(param,
"FALSE")) {
1076 "Server does not support tick!");
1078 "This server is too old to support this client!");
1081 }
else if (!strcmp(cmd,
"extendedTextInfos")) {
1088 for (
int i = 1; i < 20; i++) {
1090 snprintf(exttext,
sizeof(exttext),
"toggleextendedtext %d", i);
1096 "Got setup for a command we don't understand: %s %s",
1115 LOG(
LOG_INFO,
"common::AddMeFail",
"addme_failed received.");
1133 LOG(
LOG_DEBUG,
"common::AddMeSuccess",
"addme_success received.");
1151 LOG(
LOG_WARNING,
"common::GoodbyeCmd",
"Received goodbye command from server - exiting");
1168 if (anum < 0 || anum >
MAXANIM) {
1169 LOG(
LOG_WARNING,
"common::AnimCmd",
"animation number invalid: %d", anum);
1176 LOG(
LOG_WARNING,
"common::AnimCmd",
"num animations invalid: %d",
1181 for (i = 4, j = 0; i < len; i += 2, j++) {
1187 "Calculated animations does not equal stored animations? (%d!=%d)",
1195 LOG(
LOG_DEBUG,
"common::AnimCmd",
"Received animation %d, %d faces", anum,
animations[anum].num_animations);
1229 int color = atoi(data);
1234 buf = strchr(data,
' ');
1255 while (current != NULL) {
1256 if (current->
type == type) {
1260 current = current->
next;
1263 current->
type = type;
1276 while (current != NULL) {
1277 if (current->
type == type) {
1280 current = current->
next;
1299 while (wordCount > 0) {
1300 while (buf[0] ==
' ') {
1304 while (buf[0] !=
' ') {
1305 if (buf[0] ==
'\0') {
1307 "common::DrawExtInfoCmd",
"Data is missing %d parameters %s",
1315 if (buf[0] ==
' ') {
1319 wordCount = sscanf(data,
"%d %d %d", &color, &type, &subtype);
1320 if (wordCount != 3) {
1322 "common::DrawExtInfoCmd",
"Wrong parameters received. Could only parse %d out of 3 int in %s",
1330 "common::DrawExtInfoCmd",
"Server send us a type %d but i can't find any callback for it",
1334 fnct(color, type, subtype, buf);
1358 }
while(next != skill_id && next >= 0);
1370 int i = 0, c,
redraw = 0;
1518 int rlen = data[i++];
1519 strncpy(
cpl.
range, (
const char*)data+i, rlen);
1526 int rlen = data[i++];
1527 strncpy(
cpl.
title, (
const char*)data+i, rlen);
1534 LOG(
LOG_WARNING,
"common::StatsCmd",
"Unknown stat number %d", c);
1541 LOG(
LOG_WARNING,
"common::StatsCmd",
"got stats overflow, processed %d bytes out of %d", i, len);
1559 guint8 flags = atoi(data);
1573 buf = strchr(data,
' ');
1581 while ((buf = strchr(buf,
'\n')) != NULL) {
1632 int tag, weight, face, i = 0, nlen;
1642 memcpy(name, (
const char*)data+i, nlen);
1647 LOG(
LOG_WARNING,
"common::PlayerCmd",
"lengths do not match (%d!=%d)", len, i);
1678 int weight, loc, tag, face, flags, pos = 0, nlen, anim, nrof, type;
1686 LOG(
LOG_WARNING,
"common::common_item_command",
"Got location with no other data");
1688 }
else if (loc < 0) {
1689 LOG(
LOG_WARNING,
"common::common_item_command",
"Got location with negative value (%d)", loc);
1702 memcpy(name, (
char*)data+pos, nlen);
1707 animspeed = data[pos++];
1712 update_item(tag, loc, name, weight, face, flags, anim, animspeed, nrof, type);
1716 LOG(
LOG_WARNING,
"common::common_item_cmd",
"Overread buffer: %d > %d", pos, len);
1729 int weight, loc, tag, face, sendflags, flags, pos = 0, nlen, anim;
1735 sendflags = data[0];
1752 weight = ip->
weight*1000;
1761 LOG(
LOG_WARNING,
"common::UpdateItemCmd",
"Got tag of unknown object (%d) for new location", loc);
1778 memcpy(name, (
char*)data+pos, nlen);
1783 LOG(
LOG_WARNING,
"common::UpdateItemCmd",
"Overread buffer: %d > %d", pos, len);
1791 animspeed = data[pos++];
1802 update_item(tag, loc, name, weight, face, flags, anim, animspeed, nrof, ip->
type);
1824 LOG(
LOG_WARNING,
"common::DeleteItem",
"Cannot find tag %d", tag);
1828 LOG(
LOG_WARNING,
"common::DeleteItem",
"Overread buffer: %d > %d", pos, len);
1844 tag = atoi((
const char*)data);
1849 LOG(
LOG_WARNING,
"common::DeleteInventory",
"Invalid tag: %d", tag);
1856 static void rstrip(
char buf[
static 1],
size_t len) {
1857 for (
size_t i = len - 1; i > 0; i--) {
1858 if (buf[i] ==
'\n' || buf[i] ==
' ') {
1881 guint16 mlen, pos = 0;
1882 Spell *newspell, *tmp;
1885 newspell = calloc(1,
sizeof(
Spell));
1909 strncpy(newspell->
name, (
char*)data+pos, nlen);
1911 newspell->
name[nlen] =
'\0';
1914 strncpy(newspell->
message, (
char*)data+pos, mlen);
1916 newspell->
message[mlen] =
'\0';
1924 newspell->
usage = 0;
1927 }
else if (pos < len) {
1936 strncpy(newspell->
requirements, (
char*) data+pos, nlen);
1952 tmp->
next = newspell;
1958 LOG(
LOG_WARNING,
"common::AddspellCmd",
"Overread buffer: %d > %d", pos, len);
1969 LOG(
LOG_WARNING,
"common::UpdspellCmd",
"I know no spells to update");
1996 LOG(
LOG_WARNING,
"common::UpdspellCmd",
"Overread buffer: %d > %d", pos, len);
2003 Spell *tmp, *target;
2006 LOG(
LOG_WARNING,
"common::DeleteSpell",
"I know no spells to delete");
2074 #define NUM_LAYERS (MAP1_LAYERS-1)
2083 int mask, x, y, pos = 0, space_len, value;
2133 space_len = type>>5;
2140 value = data[pos++];
2153 LOG(
LOG_WARNING,
"commands.c::Map2Cmd",
"got layer >= MAXLAYERS!");
2156 assert(0 <= layer && layer <
MAXLAYERS);
2165 if (space_len > 2) {
2176 if (space_len > 3) {
2202 buf = strchr(data,
' ');
2224 int ExtSmooth(
unsigned char *data,
int len,
int x,
int y,
int layer)
2226 static int dx[8] = { 0, 1, 1, 1, 0, -1, -1, -1, };
2227 static int dy[8] = { -1, -1, 0, 1, 1, 1, 0, -1, };
2240 for (i = 0; i < 8; i++) {
2264 int mask, x, y, pos = 0, layer;
2287 while (pos+entrysize+2 <= len) {
2290 x = (mask>>10)&0x3f;
2292 for (layer =
NUM_LAYERS; layer >= 0; layer--) {
2293 if (mask&(1<<layer)) {
2295 if (pos+entrysize > len) {
2298 startpackentry = pos;
2309 pos = startpackentry+entrysize;
2331 LOG(
LOG_WARNING,
"common::MagicMapCmd",
"Was not able to properly extract magic map size, pos");
2343 for (cp = data, i = 0; i < 4 && cp < data+len; cp++) {
2349 LOG(
LOG_WARNING,
"common::MagicMapCmd",
"Was unable to find start of magic map data");
2354 LOG(
LOG_WARNING,
"common::MagicMapCmd",
"Magic map size mismatch. Have %d bytes, should have %d",
2425 cp = strchr(buf,
' ');
2433 if (!strcmp(buf,
"accountlogin")) {
2435 }
else if (!strcmp(buf,
"accountnew")) {
2437 }
else if (!strcmp(buf,
"accountaddplayer")) {
2439 }
else if (!strcmp(buf,
"createplayer")) {
2441 }
else if (!strcmp(buf,
"accountpw")) {
2443 }
else if (!strcmp(buf,
"accountplay")) {
2455 LOG(
LOG_ERROR,
"common::FailureCmd",
"Got a failure response we can not handle: %s:%s",
2463 int level, pos, faceno;
2502 if ((pos +flen) > len || flen>=
MAX_BUF) {
2503 LOG(
LOG_ERROR,
"commands.c:AccountPlayerCmd",
"data overran buffer");
2508 strncpy(name, buf + pos +1, flen-1);
2513 strncpy(
class, buf + pos +1, flen-1);
2518 strncpy(race, buf + pos +1, flen-1);
2523 strncpy(face, buf + pos +1, flen-1);
2528 strncpy(party, buf + pos +1, flen-1);
2533 strncpy(
map, buf + pos +1, flen-1);
void DeleteSpell(unsigned char *data, int len)
gint16 skill_level[MAX_SKILL]
struct MapCell * mapdata_cell(const int x, const int y)
@ LOG_INFO
Minor, non-harmful issues.
static gboolean redraw(gpointer data)
void item_actions(item *op)
void TickCmd(guint8 *data, int len)
void mapdata_clear_space(int x, int y)
short GetShort_String(const unsigned char *data)
@ LOG_WARNING
Warning that something might not work.
void client_tick(guint32 tick)
void(* ExtTextManager)(int flag, int type, int subtype, char *message)
gint64 skill_exp[MAX_SKILL]
#define MAP2_COORD_OFFSET
void setTextManager(int type, ExtTextManager callback)
void GoodbyeCmd(char *data, int len)
static void get_race_info(unsigned char *data, int len)
void free_all_race_class_info(Race_Class_Info *data, int num_entries)
void DeleteItem(unsigned char *data, int len)
void handle_query(char *data, int len)
void draw_stats(int redraw)
void mapdata_set_face_layer(int x, int y, gint16 face, int layer)
#define CS_STAT_SPELL_DENY
void remove_item_inventory(item *op)
void mapdata_newmap(void)
void starting_map_update_info()
void hide_all_login_windows(void)
#define CS_QUERY_SINGLECHAR
Face_Information face_info
static void get_exp_info(const unsigned char *data, int len)
void new_player(long tag, char *name, long weight, long face)
int GetInt_String(const unsigned char *data)
static int rc_compar(const Race_Class_Info *a, const Race_Class_Info *b)
void mapdata_set_smooth(int x, int y, guint8 smooth, int layer)
void script_lua_stats(void)
void update_item(int tag, int loc, char *name, int weight, int face, int flags, int anim, int animspeed, guint32 nrof, int type)
void mapdata_set_check_space(int x, int y)
void display_map_doneupdate(int redraw, int notice)
void client_pickup(guint32 pickup)
void DrawExtInfoCmd(char *data, int len)
#define MSG_TYPE_CLIENT_COMMAND
void new_char_window_update_info()
void start_login(int method)
void ReplyInfoCmd(unsigned char *buf, int len)
void AddMeFail(char *data, int len)
void PlayerCmd(unsigned char *data, int len)
struct TextManager * next
static void get_starting_map_info(unsigned char *data, int len)
#define CS_STAT_RESIST_START
void SmoothCmd(unsigned char *data, int len)
int ExtSmooth(unsigned char *data, int len, int x, int y, int layer)
void mapdata_clear_old(int x, int y)
void MapExtendedCmd(unsigned char *data, int len)
void SinkCmd(unsigned char *data, int len)
void account_change_password_failure(char *message)
void NewmapCmd(unsigned char *data, int len)
void open_container(item *op)
struct Spell_struct * next
void draw_magic_map(void)
#define CS_STAT_SPELL_REPEL
void close_container(item *op)
int last_used_skills[MAX_SKILL+1]
#define NUM_NEW_CHAR_STATS
void get_image_info(guint8 *data, int len)
void FailureCmd(char *buf, int len)
struct RC_Choice * rc_choice
void free_all_starting_map_info()
#define MSG_TYPE_CLIENT_SERVER
void Map2Cmd(unsigned char *data, int len)
void account_login_failure(char *message)
void PickupCmd(guint8 *data, int len)
void get_image_sums(char *data, int len)
void mapdata_set_anim_layer(int x, int y, guint16 anim, guint8 anim_speed, int layer)
#define ASSERT_LEN(function, curpos, buflen)
#define CS_STAT_SKILLINFO
void map_scrollCmd(char *data, int len)
void LOG(LogLevel level, const char *origin, const char *format,...)
TextManager * firstTextManager
#define MAP2_TYPE_DARKNESS
int cs_print_string(GSocketConnection *fd, const char *str,...)
void send_reply(const char *text)
void create_new_character_failure(char *message)
void addsmooth(guint16 face, guint16 smooth_face)
void DrawInfoCmd(char *data, int len)
#define INFO_MAP_ARCH_NAME
Starting_Map_Info * starting_map_info
gint16 want_config[CONFIG_NUMS]
void draw_ext_info(int orig_color, int type, int subtype, const char *message)
gint8 stat_adj[NUM_NEW_CHAR_STATS]
void update_character_choose(const char *name, const char *class, const char *race, const char *face, const char *party, const char *map, int level, int faceno)
#define CS_STAT_WEIGHT_LIM
static void get_skill_info(char *data, int len)
void StatsCmd(unsigned char *data, int len)
void UpdspellCmd(unsigned char *data, int len)
void account_add_character_failure(char *message)
struct Stat_Mapping stat_mapping[NUM_NEW_CHAR_STATS]
void draw_prompt(const char *str)
#define CS_STAT_SPELL_ATTUNE
void choose_character_init(void)
bool mapdata_contains(int x, int y)
Animations animations[MAXANIM]
void resize_map_window(int x, int y)
void remove_item(item *op)
@ LOG_ERROR
Warning that something definitely didn't work.
static void process_race_class_info(unsigned char *data, int len, Race_Class_Info *rci)
item * locate_item(gint32 tag)
static void get_class_info(unsigned char *data, int len)
void mapdata_scroll(int dx, int dy)
void Item2Cmd(unsigned char *data, int len)
void AddMeSuccess(char *data, int len)
void MagicMapCmd(unsigned char *data, int len)
void AddspellCmd(unsigned char *data, int len)
void mapdata_set_size(int viewx, int viewy)
void account_creation_failure(char *message)
void show_main_client(void)
static ExtTextManager getTextManager(int type)
static int spellmon_level
void mapdata_set_darkness(int x, int y, int darkness)
void AnimCmd(unsigned char *data, int len)
gint16 use_config[CONFIG_NUMS]
void AccountPlayersCmd(char *buf, int len)
#define MSG_TYPE_CLIENT_QUERY
void DeleteInventory(unsigned char *data, int len)
void draw_message_window(int redraw)
void update_login_info(int type)
gint64 GetInt64_String(const unsigned char *data)
char GetChar_String(const unsigned char *data)
static const char *const short_stat_name[NUM_STATS]
void SetupCmd(char *buf, int len)
void use_skill(int skill_id)
#define CS_STAT_RESIST_END
char * skill_names[MAX_SKILL]
@ LOG_DEBUG
Useful debugging information.
Race_Class_Info * classes
static void get_new_char_info(unsigned char *data, int len)
#define INFO_MAP_DESCRIPTION
void client_mapsize(int width, int height)
void UpdateItemCmd(unsigned char *data, int len)
void set_weight_limit(guint32 wlim)
#define CS_QUERY_HIDEINPUT
static void rstrip(char buf[static 1], size_t len)