Atrinik Server 2.5
server/utils.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 
00030 #include <global.h>
00031 
00043 int rndm(int min, int max)
00044 {
00045     if (max < 1 || max - min + 1 < 1)
00046     {
00047         LOG(llevBug, "Calling rndm() with min=%d max=%d\n", min, max);
00048         return min;
00049     }
00050 
00051     return min + RANDOM() / (RAND_MAX / (max - min + 1) + 1);
00052 }
00053 
00058 int rndm_chance(uint32 n)
00059 {
00060     if (!n)
00061     {
00062         LOG(llevBug, "Calling rndm_chance() with n=0.\n");
00063         return 0;
00064     }
00065 
00066     return (uint32) RANDOM() < (RAND_MAX + 1U) / n;
00067 }
00068 
00075 int look_up_spell_name(const char *spname)
00076 {
00077     int i;
00078 
00079     for (i = 0; i < NROFREALSPELLS; i++)
00080     {
00081         if (strcmp(spname, spells[i].name) == 0)
00082         {
00083             return i;
00084         }
00085     }
00086 
00087     return -1;
00088 }
00089 
00094 void replace(const char *src, const char *key, const char *replacement, char *result, size_t resultsize)
00095 {
00096     size_t resultlen, keylen;
00097 
00098     /* special case to prevent infinite loop if key == replacement == "" */
00099     if (strcmp(key, replacement) == 0)
00100     {
00101         snprintf(result, resultsize, "%s", src);
00102         return;
00103     }
00104 
00105     keylen = strlen(key);
00106     resultlen = 0;
00107 
00108     while (*src != '\0' && resultlen + 1 < resultsize)
00109     {
00110         if (strncmp(src, key, keylen) == 0)
00111         {
00112             snprintf(result + resultlen, resultsize - resultlen, "%s", replacement);
00113             resultlen += strlen(result + resultlen);
00114             src += keylen;
00115         }
00116         else
00117         {
00118             result[resultlen++] = *src++;
00119         }
00120     }
00121 
00122     result[resultlen] = '\0';
00123 }
00124 
00131 char *cleanup_string(char *ustring)
00132 {
00133     /* Trim all left whitespace */
00134     while (*ustring != '\0' && (isspace(*ustring) || !isprint(*ustring)))
00135     {
00136         ustring++;
00137     }
00138 
00139     /* This happens when whitespace only string was submitted. */
00140     if (!ustring || *ustring == '\0')
00141     {
00142         return NULL;
00143     }
00144 
00145     return ustring;
00146 }
00147 
00154 const char *get_word_from_string(const char *str, int *pos)
00155 {
00156     /* this is used for controlled input which never should bigger than this */
00157     static char buf[HUGE_BUF];
00158     int i = 0;
00159 
00160     buf[0] = '\0';
00161 
00162     while (*(str + (*pos)) != '\0' && (!isalnum(*(str + (*pos))) && !isalpha(*(str + (*pos)))))
00163     {
00164         (*pos)++;
00165     }
00166 
00167     /* Nothing left. */
00168     if (*(str + (*pos)) == '\0')
00169     {
00170         return NULL;
00171     }
00172 
00173     /* Copy until end of string or whitespace */
00174     while (*(str + (*pos)) != '\0' && (isalnum(*(str + (*pos))) || isalpha(*(str + (*pos)))))
00175     {
00176         buf[i++] = *(str + (*pos)++);
00177     }
00178 
00179     buf[i] = '\0';
00180     return buf;
00181 }
00182 
00186 void adjust_player_name(char *name)
00187 {
00188     char *tmp = name;
00189 
00190     if (!tmp || *tmp == '\0')
00191     {
00192         return;
00193     }
00194 
00195     *tmp = toupper(*tmp);
00196 
00197     while (*(++tmp) != '\0')
00198     {
00199         *tmp = tolower(*tmp);
00200     }
00201 
00202     /* Trim the right whitespace */
00203     while (tmp >= name && *(tmp - 1) == ' ')
00204     {
00205         *(--tmp) = '\0';
00206     }
00207 }
00208 
00212 void replace_unprintable_chars(char *buf)
00213 {
00214     char *p;
00215 
00216     for (p = buf; *p != '\0'; p++)
00217     {
00218         if (*p < ' ' || *p > '~')
00219         {
00220             *p = ' ';
00221         }
00222     }
00223 }
00224 
00233 size_t split_string(char *str, char *array[], size_t array_size, char sep)
00234 {
00235     char *p;
00236     size_t pos;
00237 
00238     if (array_size <= 0)
00239     {
00240         return 0;
00241     }
00242 
00243     if (*str == '\0')
00244     {
00245         array[0] = str;
00246         return 1;
00247     }
00248 
00249     pos = 0;
00250     p = str;
00251 
00252     while (pos < array_size)
00253     {
00254         array[pos++] = p;
00255 
00256         while (*p != '\0' && *p != sep)
00257         {
00258             p++;
00259         }
00260 
00261         if (pos >= array_size)
00262         {
00263             break;
00264         }
00265 
00266         if (*p != sep)
00267         {
00268             break;
00269         }
00270 
00271         *p++ = '\0';
00272     }
00273 
00274     return pos;
00275 }
00276 
00280 int get_random_dir()
00281 {
00282     return rndm(1, 8);
00283 }
00284 
00289 int get_randomized_dir(int dir)
00290 {
00291     return absdir(dir + RANDOM() % 3 + RANDOM() % 3 - 2);
00292 }
00293 
00301 int buf_overflow(const char *buf1, const char *buf2, size_t bufsize)
00302 {
00303     size_t len1 = 0, len2 = 0;
00304 
00305     if (buf1)
00306     {
00307         len1 = strlen(buf1);
00308     }
00309 
00310     if (buf2)
00311     {
00312         len2 = strlen(buf2);
00313     }
00314 
00315     if ((len1 + len2) >= bufsize)
00316     {
00317         return 1;
00318     }
00319 
00320     return 0;
00321 }
00322 
00330 char *cleanup_chat_string(char *ustring)
00331 {
00332     int i;
00333 
00334     if (!ustring)
00335     {
00336         return NULL;
00337     }
00338 
00339     /* This happens when whitespace only string was submitted. */
00340     if (!ustring || *ustring == '\0')
00341     {
00342         return NULL;
00343     }
00344 
00345     /* Now clear all special characters. */
00346     for (i = 0; *(ustring + i) != '\0'; i++)
00347     {
00348         if (*(ustring + i) < ' ' || *(ustring + i) > '~')
00349         {
00350             *(ustring + i) = ' ';
00351         }
00352     }
00353 
00354     /* Kill all whitespace. */
00355     while (*ustring != '\0' && isspace(*ustring))
00356     {
00357         ustring++;
00358     }
00359 
00360     return ustring;
00361 }
00362 
00367 char *format_number_comma(uint64 num)
00368 {
00369     static char retbuf[4 * (sizeof(uint64) * CHAR_BIT + 2) / 3 / 3 + 1];
00370     char *buf;
00371     int i = 0;
00372 
00373     buf = &retbuf[sizeof(retbuf) - 1];
00374     *buf = '\0';
00375 
00376     do
00377     {
00378         if (i % 3 == 0 && i != 0)
00379         {
00380             *--buf = ',';
00381         }
00382 
00383         *--buf = '0' + num % 10;
00384         num /= 10;
00385         i++;
00386     }
00387     while (num != 0);
00388 
00389     return buf;
00390 }
00391 
00396 void copy_file(const char *filename, FILE *fpout)
00397 {
00398     FILE *fp;
00399     char buf[HUGE_BUF];
00400 
00401     fp = fopen(filename, "r");
00402 
00403     if (!fp)
00404     {
00405         LOG(llevBug, "copy_file(): Failed to open '%s'.\n", filename);
00406         return;
00407     }
00408 
00409     while (fgets(buf, sizeof(buf), fp))
00410     {
00411         fputs(buf, fpout);
00412     }
00413 
00414     fclose(fp);
00415 }
00416 
00422 void convert_newline(char *str)
00423 {
00424     char *next, buf[MAX_BUF];
00425 
00426     while ((next = strstr(str, "\\n")))
00427     {
00428         *next = '\n';
00429         *(next + 1) = '\0';
00430         snprintf(buf, sizeof(buf), "%s%s", str, next + 2);
00431         strcpy(str, buf);
00432     }
00433 }
00434 
00441 void string_remove_markup(char *str)
00442 {
00443     char *cp;
00444 
00445     for (cp = str; *cp != '\0'; cp++)
00446     {
00447         if (*cp == '<')
00448         {
00449             *cp = ' ';
00450         }
00451     }
00452 }