version 1.54 | | version 1.55 |
---|
| | |
/* | | /* |
* static char *rcsid_init_c = | | * static char *rcsid_init_c = |
* "$Id: request.c,v 1.54 2003/12/01 05:45:18 mwedel Exp $"; | | * "$Id: request.c,v 1.55 2003/12/02 18:51:44 ryo_saeba Exp $"; |
*/ | | */ |
| | |
/* | | /* |
| | |
The author can be reached via e-mail to crossfire-devel@real-time.com | | The author can be reached via e-mail to crossfire-devel@real-time.com |
*/ | | */ |
| | |
/* | | /** |
| | * \file |
| | * Client handling. |
| | * |
| | * \date 2003-12-02 |
| | * |
* This file implements all of the goo on the server side for handling | | * This file implements all of the goo on the server side for handling |
* clients. It's got a bunch of global variables for keeping track of | | * clients. It's got a bunch of global variables for keeping track of |
* each of the clients. | | * each of the clients. |
| | |
| | |
#include "sounds.h" | | #include "sounds.h" |
| | |
/* This table translates the attack numbers as used within the | | /** |
| | * This table translates the attack numbers as used within the |
* program to the value we use when sending STATS command to the | | * program to the value we use when sending STATS command to the |
* client. IF a value is -1, then we don't send that to the | | * client. If a value is -1, then we don't send that to the |
* client. | | * client. |
*/ | | */ |
short atnr_cs_stat[NROFATTACKS] = {CS_STAT_RES_PHYS, | | short atnr_cs_stat[NROFATTACKS] = {CS_STAT_RES_PHYS, |
| | |
-1 /* Disease - not fully done yet */ | | -1 /* Disease - not fully done yet */ |
}; | | }; |
| | |
/* This is the Setup cmd - easy first implementation */ | | /** This is the Setup cmd - easy first implementation */ |
void SetUp(char *buf, int len, NewSocket *ns) | | void SetUp(char *buf, int len, NewSocket *ns) |
{ | | { |
int s; | | int s; |
| | |
Write_String_To_Socket(ns, cmdback, strlen(cmdback)); | | Write_String_To_Socket(ns, cmdback, strlen(cmdback)); |
} | | } |
| | |
/* The client has requested to be added to the game. This is what | | /** |
* takes care of it. We tell the client how things worked out. | | * The client has requested to be added to the game. |
| | * This is what takes care of it. We tell the client how things worked out. |
* I am not sure if this file is the best place for this function. however, | | * I am not sure if this file is the best place for this function. however, |
* it either has to be here or init_sockets needs to be exported. | | * it either has to be here or init_sockets needs to be exported. |
*/ | | */ |
| | |
settings=oldsettings; | | settings=oldsettings; |
} | | } |
| | |
| | /** Reply to ExtendedInfos command */ |
void ToggleExtendedInfos (char *buf, int len, NewSocket *ns){ | | void ToggleExtendedInfos (char *buf, int len, NewSocket *ns){ |
char cmdback[MAX_BUF]; | | char cmdback[MAX_BUF]; |
char command[50]; | | char command[50]; |
| | |
SockList_AddShort(&sl, smoothface); | | SockList_AddShort(&sl, smoothface); |
Send_With_Handling(ns, &sl); | | Send_With_Handling(ns, &sl); |
} | | } |
/* This handles the general commands from the client (ie, north, fire, cast, | | |
| | /** |
| | * This handles the general commands from the client (ie, north, fire, cast, |
* etc.) | | * etc.) |
*/ | | */ |
void PlayerCmd(char *buf, int len, player *pl) | | void PlayerCmd(char *buf, int len, player *pl) |
| | |
} | | } |
| | |
| | |
/* This handles the general commands from the client (ie, north, fire, cast, | | /** |
* etc.) It is a lot like PlayerCmd above, but is called with the | | * This handles the general commands from the client (ie, north, fire, cast, |
| | * etc.). It is a lot like PlayerCmd above, but is called with the |
* 'ncom' method which gives more information back to the client so it | | * 'ncom' method which gives more information back to the client so it |
* can throttle. | | * can throttle. |
*/ | | */ |
| | |
} | | } |
| | |
| | |
/* This is a reply to a previous query. */ | | /** This is a reply to a previous query. */ |
void ReplyCmd(char *buf, int len, player *pl) | | void ReplyCmd(char *buf, int len, player *pl) |
{ | | { |
/* This is to synthesize how the data would be stored if it | | /* This is to synthesize how the data would be stored if it |
| | |
} | | } |
} | | } |
| | |
/* Client tells its version. If there is a mismatch, we close the | | /** |
| | * Client tells its version. If there is a mismatch, we close the |
* socket. In real life, all we should care about is the client having | | * socket. In real life, all we should care about is the client having |
* something older than the server. If we assume the client will be | | * something older than the server. If we assume the client will be |
* backwards compatible, having it be a later version should not be a | | * backwards compatible, having it be a later version should not be a |
| | |
} | | } |
} | | } |
| | |
/* sound related functions. */ | | /** sound related functions. */ |
| | |
void SetSound(char *buf, int len, NewSocket *ns) | | void SetSound(char *buf, int len, NewSocket *ns) |
{ | | { |
ns->sound = atoi(buf); | | ns->sound = atoi(buf); |
} | | } |
| | |
/* client wants the map resent */ | | /** client wants the map resent */ |
| | |
void MapRedrawCmd(char *buff, int len, player *pl) | | void MapRedrawCmd(char *buff, int len, player *pl) |
{ | | { |
| | |
draw_client_map(pl->ob); | | draw_client_map(pl->ob); |
} | | } |
| | |
| | /** Newmap command */ |
void MapNewmapCmd( player *pl) | | void MapNewmapCmd( player *pl) |
{ | | { |
if( pl->socket.newmapcmd == 1) | | if( pl->socket.newmapcmd == 1) |
| | |
| | |
| | |
| | |
/* Moves and object (typically, container to inventory | | /** |
* move <to> <tag> <nrof> | | * Moves an object (typically, container to inventory). |
| | * syntax is: move (to) (tag) (nrof) |
*/ | | */ |
void MoveCmd(char *buf, int len,player *pl) | | void MoveCmd(char *buf, int len,player *pl) |
{ | | { |
| | |
* | | * |
******************************************************************************/ | | ******************************************************************************/ |
| | |
/* | | /** |
* send_query asks the client to query the user. This way, the client knows | | * Asks the client to query the user. This way, the client knows |
* it needs to send something back (vs just printing out a message | | * it needs to send something back (vs just printing out a message) |
*/ | | */ |
void send_query(NewSocket *ns, uint8 flags, char *text) | | void send_query(NewSocket *ns, uint8 flags, char *text) |
{ | | { |
| | |
Write_String_To_Socket(ns, buf, strlen(buf)); | | Write_String_To_Socket(ns, buf, strlen(buf)); |
} | | } |
| | |
| | |
/* Sends the stats to the client - only sends them if they have changed */ | | |
| | |
#define AddIfInt64(Old,New,Type) if (Old != New) {\ | | #define AddIfInt64(Old,New,Type) if (Old != New) {\ |
Old = New; \ | | Old = New; \ |
SockList_AddChar(&sl, Type); \ | | SockList_AddChar(&sl, Type); \ |
| | |
sl.len += strlen(New); \ | | sl.len += strlen(New); \ |
} | | } |
| | |
/* | | /** |
* esrv_update_stats sends a statistics update. We look at the old values, | | * Sends a statistics update. We look at the old values, |
* and only send what has changed. Stat mapping values are in newclient.h | | * and only send what has changed. Stat mapping values are in newclient.h |
* Since this gets sent a lot, this is actually one of the few binary | | * Since this gets sent a lot, this is actually one of the few binary |
* commands for now. | | * commands for now. |
| | |
} | | } |
| | |
| | |
/* Tells the client that here is a player it should start using. | | /** |
| | * Tells the client that here is a player it should start using. |
*/ | | */ |
| | |
void esrv_new_player(player *pl, uint32 weight) | | void esrv_new_player(player *pl, uint32 weight) |
{ | | { |
SockList sl; | | SockList sl; |
| | |
} | | } |
| | |
| | |
/* Need to send an animation sequence to the client. | | /** |
| | * Need to send an animation sequence to the client. |
* We will send appropriate face commands to the client if we haven't | | * We will send appropriate face commands to the client if we haven't |
* sent them the face yet (this can become quite costly in terms of | | * sent them the face yet (this can become quite costly in terms of |
* how much we are sending - on the other hand, this should only happen | | * how much we are sending - on the other hand, this should only happen |
| | |
* | | * |
******************************************************************************/ | | ******************************************************************************/ |
| | |
/* This adds face_num to a map cell at x,y. If the client doesn't have | | /** |
| | * This adds face_num to a map cell at x,y. If the client doesn't have |
* the face yet, we will also send it. | | * the face yet, we will also send it. |
*/ | | */ |
static void esrv_map_setbelow(NewSocket *ns, int x,int y, | | static void esrv_map_setbelow(NewSocket *ns, int x,int y, |
| | |
struct LayerCell lcells[MAP_CLIENT_X * MAP_CLIENT_Y]; | | struct LayerCell lcells[MAP_CLIENT_X * MAP_CLIENT_Y]; |
}; | | }; |
| | |
| | /** Checkes if map cells have changed */ |
static int mapcellchanged(NewSocket *ns,int i,int j, struct Map *newmap) | | static int mapcellchanged(NewSocket *ns,int i,int j, struct Map *newmap) |
{ | | { |
int k; | | int k; |
| | |
return 0; | | return 0; |
} | | } |
| | |
| | /** |
/* cnum is the client number, cur is the the buffer we put all of | | * Basically, what this does is pack the data into layers. |
| | * cnum is the client number, cur is the the buffer we put all of |
* this data into. we return the end of the data. layers is | | * this data into. we return the end of the data. layers is |
* how many layers of data we should back. | | * how many layers of data we should back. |
* Basically, what this does is pack the data into layers. | | |
*/ | | */ |
static uint8 *compactlayer(NewSocket *ns, unsigned char *cur, int numlayers, | | static uint8 *compactlayer(NewSocket *ns, unsigned char *cur, int numlayers, |
struct Map *newmap) | | struct Map *newmap) |
| | |
} | | } |
| | |
| | |
/* Clears a map cell */ | | /** Clears a map cell */ |
static void map_clearcell(struct MapCell *cell, int face0, int face1, int face2, int count) | | static void map_clearcell(struct MapCell *cell, int face0, int face1, int face2, int count) |
{ | | { |
cell->count=count; | | cell->count=count; |
| | |
| | |
static object *heads[MAX_HEAD_POS * MAX_HEAD_POS * MAX_LAYERS]; | | static object *heads[MAX_HEAD_POS * MAX_HEAD_POS * MAX_LAYERS]; |
| | |
/* simple function - returns true of any of the heads for this | | /** |
| | * Returns true of any of the heads for this |
* space is set. Returns 0 if all are blank - this is used | | * space is set. Returns 0 if all are blank - this is used |
* for empty space checking. | | * for empty space checking. |
*/ | | */ |
| | |
return 0; | | return 0; |
} | | } |
| | |
/* check_head is a bit simplistic version of update_space below. | | /** |
| | * check_head is a bit simplistic version of update_space below. |
* basically, it only checks the that the head on space ax,ay at layer | | * basically, it only checks the that the head on space ax,ay at layer |
* needs to get sent - if so, it adds the data, sending the head | | * needs to get sent - if so, it adds the data, sending the head |
* if needed, and returning 1. If this no data needs to get | | * if needed, and returning 1. If this no data needs to get |
| | |
return 0; /* No change */ | | return 0; /* No change */ |
} | | } |
| | |
/* Removes the need to replicate the same code for each layer. | | /** |
| | * Removes the need to replicate the same code for each layer. |
* this returns true if this space is now in fact different than | | * this returns true if this space is now in fact different than |
* it was. | | * it was. |
* sl is the socklist this data is going into. | | * sl is the socklist this data is going into. |
| | |
return 0; | | return 0; |
} | | } |
| | |
/* This function is mainly a copy of update_space, | | /** |
| | * This function is mainly a copy of update_space, |
* except it handles update of the smoothing updates, | | * except it handles update of the smoothing updates, |
* not the face updates. | | * not the face updates. |
* Removes the need to replicate the same code for each layer. | | * Removes the need to replicate the same code for each layer. |
| | |
/* Nothing changed */ | | /* Nothing changed */ |
return 0; | | return 0; |
} | | } |
/* returns the size of a data for a map square as returned by | | /** |
| | * Returns the size of a data for a map square as returned by |
* mapextended. There are CLIENTMAPX*CLIENTMAPY*LAYERS entries | | * mapextended. There are CLIENTMAPX*CLIENTMAPY*LAYERS entries |
* available. | | * available. |
*/ | | */ |
| | |
} | | } |
return result; | | return result; |
} | | } |
/* this function uses the new map1 protocol command to send the map | | /** |
| | * This function uses the new map1 protocol command to send the map |
* to the client. It is necessary because the old map command supports | | * to the client. It is necessary because the old map command supports |
* a maximum map size of 15x15. | | * a maximum map size of 15x15. |
* This function is much simpler than the old one. This is because | | * This function is much simpler than the old one. This is because |
| | |
free(sl.buf); | | free(sl.buf); |
} | | } |
| | |
| | /** |
| | * Draws client map. |
| | */ |
void draw_client_map(object *pl) | | void draw_client_map(object *pl) |
{ | | { |
int i,j,nx,ny; /* ax and ay goes from 0 to max-size of arrays */ | | int i,j,nx,ny; /* ax and ay goes from 0 to max-size of arrays */ |
| | |
cs_write_string(&pl->contr->socket,buf,strlen(buf)); | | cs_write_string(&pl->contr->socket,buf,strlen(buf)); |
} | | } |
| | |
/* This sends the skill number to name mapping. We ignore | | /** |
| | * This sends the skill number to name mapping. We ignore |
* the params - we always send the same info no matter what. | | * the params - we always send the same info no matter what. |
*/ | | */ |
void send_skill_info(NewSocket *ns, char *params) | | void send_skill_info(NewSocket *ns, char *params) |