Atrinik Server 2.5
socket/info.c
Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team    *
00005 *                                                                       *
00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game)     *
00007 * and Crossfire (Multiplayer game for X-windows).                       *
00008 *                                                                       *
00009 * This program is free software; you can redistribute it and/or modify  *
00010 * it under the terms of the GNU General Public License as published by  *
00011 * the Free Software Foundation; either version 2 of the License, or     *
00012 * (at your option) any later version.                                   *
00013 *                                                                       *
00014 * This program is distributed in the hope that it will be useful,       *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017 * GNU General Public License for more details.                          *
00018 *                                                                       *
00019 * You should have received a copy of the GNU General Public License     *
00020 * along with this program; if not, write to the Free Software           *
00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             *
00022 *                                                                       *
00023 * The author can be reached at admin@atrinik.org                        *
00024 ************************************************************************/
00025 
00037 #include <global.h>
00038 #include <stdarg.h>
00039 
00040 int color_notation_to_flag(const char *color)
00041 {
00042     if (!strcmp(color, COLOR_WHITE))
00043     {
00044         return 0;
00045     }
00046     else if (!strcmp(color, COLOR_ORANGE))
00047     {
00048         return 1;
00049     }
00050     else if (!strcmp(color, COLOR_NAVY))
00051     {
00052         return 2;
00053     }
00054     else if (!strcmp(color, COLOR_RED))
00055     {
00056         return 3;
00057     }
00058     else if (!strcmp(color, COLOR_GREEN))
00059     {
00060         return 4;
00061     }
00062     else if (!strcmp(color, COLOR_BLUE))
00063     {
00064         return 5;
00065     }
00066     else if (!strcmp(color, COLOR_GRAY))
00067     {
00068         return 6;
00069     }
00070     else if (!strcmp(color, COLOR_BROWN))
00071     {
00072         return 7;
00073     }
00074     else if (!strcmp(color, COLOR_PURPLE))
00075     {
00076         return 8;
00077     }
00078     else if (!strcmp(color, COLOR_PINK))
00079     {
00080         return 9;
00081     }
00082     else if (!strcmp(color, COLOR_YELLOW))
00083     {
00084         return 10;
00085     }
00086     else if (!strcmp(color, COLOR_DK_NAVY))
00087     {
00088         return 11;
00089     }
00090     else if (!strcmp(color, COLOR_DK_GREEN))
00091     {
00092         return 12;
00093     }
00094     else if (!strcmp(color, COLOR_DK_ORANGE))
00095     {
00096         return 17;
00097     }
00098     else if (!strcmp(color, COLOR_BRIGHT_PURPLE))
00099     {
00100         return 197;
00101     }
00102     else if (!strcmp(color, COLOR_HGOLD))
00103     {
00104         return 64;
00105     }
00106     else if (!strcmp(color, COLOR_DGOLD))
00107     {
00108         return 65;
00109     }
00110 
00111     return 0;
00112 }
00113 
00120 void new_draw_info(int flags, const char *color, object *pl, const char *buf)
00121 {
00122     unsigned char info_string[HUGE_BUF];
00123     size_t len;
00124     SockList sl;
00125 
00126     /* Handle global messages. */
00127     if (flags & NDI_ALL)
00128     {
00129         player *tmppl;
00130 
00131         for (tmppl = first_player; tmppl; tmppl = tmppl->next)
00132         {
00133             new_draw_info((flags & ~NDI_ALL), color, tmppl->ob, buf);
00134         }
00135 
00136         return;
00137     }
00138 
00139     if (!pl || pl->type != PLAYER)
00140     {
00141         return;
00142     }
00143 
00144     if (CONTR(pl) == NULL)
00145     {
00146         LOG(llevBug, "new_draw_info(): Called for player with contr == NULL! %s (%x) msg: %s\n", query_name(pl, NULL), flags, buf);
00147         return;
00148     }
00149 
00150     if (CONTR(pl)->state != ST_PLAYING)
00151     {
00152         return;
00153     }
00154 
00155     sl.buf = info_string;
00156     SOCKET_SET_BINARY_CMD(&sl, BINARY_CMD_DRAWINFO2);
00157     if (CONTR(pl)->socket.socket_version >= 1055)
00158     {
00159     SockList_AddShort(&sl, flags);
00160     SockList_AddString(&sl, color);
00161     }
00162     else
00163     {
00164     SockList_AddShort(&sl, flags | color_notation_to_flag(color));
00165     }
00166     /* Make sure we don't copy more bytes than available space in the buffer. */
00167     len = MIN(strlen(buf), sizeof(info_string) - sl.len - 1);
00168     memcpy((char *) sl.buf + sl.len, buf, len);
00169     sl.len += len;
00170 
00171     /* Terminate the string. */
00172     SockList_AddChar(&sl, '\0');
00173     Send_With_Handling(&CONTR(pl)->socket, &sl);
00174 }
00175 
00183 void new_draw_info_format(int flags, const char *color, object *pl, char *format, ...)
00184 {
00185     char buf[HUGE_BUF];
00186 
00187     va_list ap;
00188     va_start(ap, format);
00189     vsnprintf(buf, sizeof(buf), format, ap);
00190     va_end(ap);
00191 
00192     new_draw_info(flags, color, pl, buf);
00193 }
00194 
00202 static void new_info_map_all_except(int flags, const char *color, mapstruct *map, object *op1, object *op, const char *str)
00203 {
00204     object *tmp;
00205 
00206     if (map->player_first)
00207     {
00208         for (tmp = map->player_first; tmp; tmp = CONTR(tmp)->map_above)
00209         {
00210             if (tmp != op && tmp != op1)
00211             {
00212                 new_draw_info(flags, color, tmp, str);
00213             }
00214         }
00215     }
00216 }
00217 
00228 void new_info_map(int flags, const char *color, mapstruct *map, int x, int y, int dist, const char *str)
00229 {
00230     int xt, yt, d;
00231     object *tmp;
00232 
00233     if (!map || map->in_memory != MAP_IN_MEMORY)
00234     {
00235         return;
00236     }
00237 
00238     if (dist != MAP_INFO_ALL)
00239     {
00240         d = POW2(dist);
00241     }
00242     else
00243     {
00244         /* We want all on this map */
00245         new_info_map_all_except(flags, color, map, NULL, NULL, str);
00246         return;
00247     }
00248 
00249     /* Any players on this map? */
00250     if (map->player_first)
00251     {
00252         for (tmp = map->player_first; tmp; tmp = CONTR(tmp)->map_above)
00253         {
00254             if ((POW2(tmp->x - x) + POW2(tmp->y - y)) <= d)
00255             {
00256                 new_draw_info(flags, color, tmp, str);
00257             }
00258         }
00259     }
00260 
00261     if (map->tile_map[0] && map->tile_map[0]->in_memory == MAP_IN_MEMORY && map->tile_map[0]->player_first)
00262     {
00263         yt = y + MAP_HEIGHT(map->tile_map[0]);
00264 
00265         for (tmp = map->tile_map[0]->player_first; tmp; tmp = CONTR(tmp)->map_above)
00266         {
00267             if ((POW2(tmp->x - x) + POW2(tmp->y - yt)) <= d)
00268             {
00269                 new_draw_info(flags, color, tmp, str);
00270             }
00271         }
00272     }
00273 
00274     if (map->tile_map[1] && map->tile_map[1]->in_memory == MAP_IN_MEMORY && map->tile_map[1]->player_first)
00275     {
00276         xt = x - MAP_WIDTH(map);
00277 
00278         for (tmp = map->tile_map[1]->player_first; tmp; tmp = CONTR(tmp)->map_above)
00279         {
00280             if ((POW2(tmp->x - xt) + POW2(tmp->y - y)) <= d)
00281             {
00282                 new_draw_info(flags, color, tmp, str);
00283             }
00284         }
00285     }
00286 
00287     if (map->tile_map[2] && map->tile_map[2]->in_memory == MAP_IN_MEMORY && map->tile_map[2]->player_first)
00288     {
00289         yt = y - MAP_HEIGHT(map);
00290 
00291         for (tmp = map->tile_map[2]->player_first; tmp; tmp = CONTR(tmp)->map_above)
00292         {
00293             if ((POW2(tmp->x - x) + POW2(tmp->y - yt)) <= d)
00294             {
00295                 new_draw_info(flags, color, tmp, str);
00296             }
00297         }
00298     }
00299 
00300     if (map->tile_map[3] && map->tile_map[3]->in_memory == MAP_IN_MEMORY && map->tile_map[3]->player_first)
00301     {
00302         xt = x + MAP_WIDTH(map->tile_map[3]);
00303 
00304         for (tmp = map->tile_map[3]->player_first; tmp; tmp = CONTR(tmp)->map_above)
00305         {
00306             if ((POW2(tmp->x - xt) + POW2(tmp->y - y)) <= d)
00307             {
00308                 new_draw_info(flags, color, tmp, str);
00309             }
00310         }
00311     }
00312 
00313     if (map->tile_map[4] && map->tile_map[4]->in_memory == MAP_IN_MEMORY && map->tile_map[4]->player_first)
00314     {
00315         yt = y + MAP_HEIGHT(map->tile_map[4]);
00316         xt = x - MAP_WIDTH(map);
00317 
00318         for (tmp = map->tile_map[4]->player_first; tmp; tmp = CONTR(tmp)->map_above)
00319         {
00320             if ((POW2(tmp->x - xt) + POW2(tmp->y - yt)) <= d)
00321             {
00322                 new_draw_info(flags, color, tmp, str);
00323             }
00324         }
00325     }
00326 
00327     if (map->tile_map[5] && map->tile_map[5]->in_memory == MAP_IN_MEMORY && map->tile_map[5]->player_first)
00328     {
00329         xt = x - MAP_WIDTH(map);
00330         yt = y - MAP_HEIGHT(map);
00331 
00332         for (tmp = map->tile_map[5]->player_first; tmp; tmp = CONTR(tmp)->map_above)
00333         {
00334             if ((POW2(tmp->x - xt) + POW2(tmp->y - yt)) <= d)
00335             {
00336                 new_draw_info(flags, color, tmp, str);
00337             }
00338         }
00339     }
00340 
00341     if (map->tile_map[6] && map->tile_map[6]->in_memory == MAP_IN_MEMORY && map->tile_map[6]->player_first)
00342     {
00343         xt = x + MAP_WIDTH(map->tile_map[6]);
00344         yt = y - MAP_HEIGHT(map);
00345 
00346         for (tmp = map->tile_map[6]->player_first; tmp; tmp = CONTR(tmp)->map_above)
00347         {
00348             if ((POW2(tmp->x - xt) + POW2(tmp->y - yt)) <= d)
00349             {
00350                 new_draw_info(flags, color, tmp, str);
00351             }
00352         }
00353     }
00354 
00355     if (map->tile_map[7] && map->tile_map[7]->in_memory == MAP_IN_MEMORY && map->tile_map[7]->player_first)
00356     {
00357         xt = x + MAP_WIDTH(map->tile_map[7]);
00358         yt = y + MAP_HEIGHT(map->tile_map[7]);
00359 
00360         for (tmp = map->tile_map[7]->player_first; tmp; tmp = CONTR(tmp)->map_above)
00361         {
00362             if ((POW2(tmp->x - xt) + POW2(tmp->y - yt)) <= d)
00363             {
00364                 new_draw_info(flags, color, tmp, str);
00365             }
00366         }
00367     }
00368 }
00369 
00382 void new_info_map_except(int flags, const char *color, mapstruct *map, int x, int y, int dist, object *op1, object *op, const char *str)
00383 {
00384     int xt, yt, d;
00385     object *tmp;
00386 
00387     if (!map || map->in_memory != MAP_IN_MEMORY)
00388     {
00389         return;
00390     }
00391 
00392     if (dist != MAP_INFO_ALL)
00393     {
00394         d = POW2(dist);
00395     }
00396     else
00397     {
00398         /* We want all on this map */
00399         new_info_map_all_except(flags, color, map, op1, op, str);
00400         return;
00401     }
00402 
00403     /* Any players on this map? */
00404     if (map->player_first)
00405     {
00406         for (tmp = map->player_first; tmp; tmp = CONTR(tmp)->map_above)
00407         {
00408             if (tmp != op && tmp != op1 && (POW2(tmp->x - x) + POW2(tmp->y - y)) <= d)
00409             {
00410                 new_draw_info(flags, color, tmp, str);
00411             }
00412         }
00413     }
00414 
00415     if (map->tile_map[0] && map->tile_map[0]->in_memory == MAP_IN_MEMORY && map->tile_map[0]->player_first)
00416     {
00417         yt = y + MAP_HEIGHT(map->tile_map[0]);
00418 
00419         for (tmp = map->tile_map[0]->player_first; tmp; tmp = CONTR(tmp)->map_above)
00420         {
00421             if (tmp != op && tmp != op1 && (POW2(tmp->x - x) + POW2(tmp->y - yt)) <= d)
00422             {
00423                 new_draw_info(flags, color, tmp, str);
00424             }
00425         }
00426     }
00427 
00428     if (map->tile_map[1] && map->tile_map[1]->in_memory == MAP_IN_MEMORY && map->tile_map[1]->player_first)
00429     {
00430         xt = x - MAP_WIDTH(map);
00431 
00432         for (tmp = map->tile_map[1]->player_first; tmp; tmp = CONTR(tmp)->map_above)
00433         {
00434             if (tmp != op && tmp != op1 && (POW2(tmp->x - xt) + POW2(tmp->y - y)) <= d)
00435             {
00436                 new_draw_info(flags, color, tmp, str);
00437             }
00438         }
00439     }
00440 
00441     if (map->tile_map[2] && map->tile_map[2]->in_memory == MAP_IN_MEMORY && map->tile_map[2]->player_first)
00442     {
00443         yt = y - MAP_HEIGHT(map);
00444 
00445         for (tmp = map->tile_map[2]->player_first; tmp; tmp = CONTR(tmp)->map_above)
00446         {
00447             if (tmp != op && tmp != op1 && (POW2(tmp->x - x) + POW2(tmp->y - yt)) <= d)
00448             {
00449                 new_draw_info(flags, color, tmp, str);
00450             }
00451         }
00452     }
00453 
00454     if (map->tile_map[3] && map->tile_map[3]->in_memory == MAP_IN_MEMORY && map->tile_map[3]->player_first)
00455     {
00456         xt = x + MAP_WIDTH(map->tile_map[3]);
00457 
00458         for (tmp = map->tile_map[3]->player_first; tmp; tmp = CONTR(tmp)->map_above)
00459         {
00460             if (tmp != op && tmp != op1 && (POW2(tmp->x - xt) + POW2(tmp->y - y)) <= d)
00461             {
00462                 new_draw_info(flags, color, tmp, str);
00463             }
00464         }
00465     }
00466 
00467     if (map->tile_map[4] && map->tile_map[4]->in_memory == MAP_IN_MEMORY && map->tile_map[4]->player_first)
00468     {
00469         yt = y + MAP_HEIGHT(map->tile_map[4]);
00470         xt = x - MAP_WIDTH(map);
00471 
00472         for (tmp = map->tile_map[4]->player_first; tmp; tmp = CONTR(tmp)->map_above)
00473         {
00474             if (tmp != op && tmp != op1 && (POW2(tmp->x - xt) + POW2(tmp->y - yt)) <= d)
00475             {
00476                 new_draw_info(flags, color, tmp, str);
00477             }
00478         }
00479     }
00480 
00481     if (map->tile_map[5] && map->tile_map[5]->in_memory == MAP_IN_MEMORY && map->tile_map[5]->player_first)
00482     {
00483         xt = x - MAP_WIDTH(map);
00484         yt = y - MAP_HEIGHT(map);
00485 
00486         for (tmp = map->tile_map[5]->player_first; tmp; tmp = CONTR(tmp)->map_above)
00487         {
00488             if (tmp != op && tmp != op1 && (POW2(tmp->x - xt) + POW2(tmp->y - yt)) <= d)
00489             {
00490                 new_draw_info(flags, color, tmp, str);
00491             }
00492         }
00493     }
00494 
00495     if (map->tile_map[6] && map->tile_map[6]->in_memory == MAP_IN_MEMORY && map->tile_map[6]->player_first)
00496     {
00497         xt = x + MAP_WIDTH(map->tile_map[6]);
00498         yt = y - MAP_HEIGHT(map);
00499 
00500         for (tmp = map->tile_map[6]->player_first; tmp; tmp = CONTR(tmp)->map_above)
00501         {
00502             if (tmp != op && tmp != op1 && (POW2(tmp->x - xt) + POW2(tmp->y - yt)) <= d)
00503             {
00504                 new_draw_info(flags, color, tmp, str);
00505             }
00506         }
00507     }
00508 
00509     if (map->tile_map[7] && map->tile_map[7]->in_memory == MAP_IN_MEMORY && map->tile_map[7]->player_first)
00510     {
00511         xt = x + MAP_WIDTH(map->tile_map[7]);
00512         yt = y + MAP_HEIGHT(map->tile_map[7]);
00513 
00514         for (tmp = map->tile_map[7]->player_first; tmp; tmp = CONTR(tmp)->map_above)
00515         {
00516             if (tmp != op && tmp != op1 && (POW2(tmp->x - xt) + POW2(tmp->y - yt)) <= d)
00517             {
00518                 new_draw_info(flags, color, tmp, str);
00519             }
00520         }
00521     }
00522 }
00523 
00533 void send_socket_message(const char *color, socket_struct *ns, const char *buf)
00534 {
00535     if (ns->socket_version >= 1055)
00536     {
00537     SockList sl;
00538     unsigned char sockbuf[HUGE_BUF];
00539     size_t len;
00540 
00541     sl.buf = sockbuf;
00542     SOCKET_SET_BINARY_CMD(&sl, BINARY_CMD_DRAWINFO);
00543 
00544     SockList_AddString(&sl, color);
00545 
00546     /* Make sure we don't copy more bytes than available space in the buffer. */
00547     len = MIN(strlen(buf), sizeof(sockbuf) - sl.len - 1);
00548     memcpy(sl.buf + sl.len, buf, len);
00549     sl.len += len;
00550 
00551     /* Terminate the string. */
00552     SockList_AddChar(&sl, '\0');
00553     Send_With_Handling(ns, &sl);
00554     }
00555     else
00556     {
00557     char tmp[HUGE_BUF];
00558     snprintf(tmp, sizeof(tmp), "X%d %s", color_notation_to_flag(color), buf);
00559     Write_String_To_Socket(ns, BINARY_CMD_DRAWINFO, tmp, strlen(tmp));
00560     }
00561 }