diff options
-rwxr-xr-x | eathena.sh | 2 | ||||
-rw-r--r-- | src/char/Makefile | 4 | ||||
-rw-r--r-- | src/char/char.c | 13 | ||||
-rw-r--r-- | src/char/int_storage.c | 9 | ||||
-rw-r--r-- | src/common/Makefile | 3 | ||||
-rw-r--r-- | src/common/core.c | 10 | ||||
-rw-r--r-- | src/common/lock.c | 11 | ||||
-rw-r--r-- | src/common/mt_rand.c | 110 | ||||
-rw-r--r-- | src/common/mt_rand.h | 8 | ||||
-rw-r--r-- | src/common/utils.h | 6 | ||||
-rw-r--r-- | src/ladmin/GNUmakefile | 4 | ||||
-rw-r--r-- | src/ladmin/Makefile | 4 | ||||
-rw-r--r-- | src/login/Makefile | 4 | ||||
-rw-r--r-- | src/login/login.c | 7 | ||||
-rw-r--r-- | src/map/Makefile | 2 | ||||
-rw-r--r-- | src/map/atcommand.c | 99 | ||||
-rw-r--r-- | src/map/atcommand.h | 2 | ||||
-rw-r--r-- | src/map/battle.c | 1 | ||||
-rw-r--r-- | src/map/clif.c | 10 | ||||
-rw-r--r-- | src/map/map.c | 6 | ||||
-rw-r--r-- | src/map/map.h | 2 | ||||
-rw-r--r-- | src/map/pc.c | 27 | ||||
-rw-r--r-- | src/map/skill.c | 136 | ||||
-rw-r--r-- | src/map/tmw.c | 67 | ||||
-rw-r--r-- | src/map/tmw.h | 1 |
25 files changed, 381 insertions, 167 deletions
@@ -15,6 +15,8 @@ SRVHOMEDIR=$HOME/tmwserver #---------------------------------------------------------------------- # main() +ulimit -u 10 + cd ${SRVHOMEDIR} eathena_start() { diff --git a/src/char/Makefile b/src/char/Makefile index d4344a0..841edfd 100644 --- a/src/char/Makefile +++ b/src/char/Makefile @@ -1,8 +1,8 @@ all: char-server txt: char-server -COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/lock.o ../common/malloc.o -COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/db.h ../common/lock.h ../common/timer.h ../common/malloc.h +COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/lock.o ../common/malloc.o ../common/mt_rand.o +COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/db.h ../common/lock.h ../common/timer.h ../common/malloc.h ../common/mt_rand.h char-server: char.o inter.o int_party.o int_guild.o int_storage.o $(COMMON_OBJ) $(CC) -o ../../$@ $> diff --git a/src/char/char.c b/src/char/char.c index 38c1f4a..fbf512e 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -720,8 +720,20 @@ void mmo_char_sync(void) { // Function to save (in a periodic way) datas in files //---------------------------------------------------- int mmo_char_sync_timer(int tid, unsigned int tick, int id, int data) { + pid_t pid; + + // This can take a lot of time. Fork a child to handle the work and return at once + // If we're unable to fork just continue running the function normally + if ((pid = fork()) > 0) + return 0; + mmo_char_sync(); inter_save(); + + // If we're a child we should suicide now. + if (pid == 0) + exit(0); + return 0; } @@ -905,7 +917,6 @@ int make_new_char(int fd, unsigned char *dat) { memcpy(&char_dat[i].save_point, &start_point, sizeof(start_point)); char_num++; - mmo_char_sync(); return i; } diff --git a/src/char/int_storage.c b/src/char/int_storage.c index 2612e17..0829384 100644 --- a/src/char/int_storage.c +++ b/src/char/int_storage.c @@ -328,6 +328,10 @@ int inter_storage_save() { FILE *fp; int lock; + + if (!storage_db) + return 1; + if( (fp=lock_fopen(storage_txt,&lock))==NULL ){ printf("int_storage: cant write [%s] !!! data is lost !!!\n",storage_txt); return 1; @@ -342,6 +346,7 @@ int inter_guild_storage_save_sub(void *key,void *data,va_list ap) { char line[65536]; FILE *fp; + if(inter_guild_search(((struct guild_storage *)data)->guild_id) != NULL) { guild_storage_tostr(line,(struct guild_storage *)data); fp=va_arg(ap,FILE *); @@ -356,6 +361,10 @@ int inter_guild_storage_save() { FILE *fp; int lock; + + if (!guild_storage_db) + return 1; + if( (fp=lock_fopen(guild_storage_txt,&lock))==NULL ){ printf("int_storage: cant write [%s] !!! data is lost !!!\n",guild_storage_txt); return 1; diff --git a/src/common/Makefile b/src/common/Makefile index b5b8f7c..9218a55 100644 --- a/src/common/Makefile +++ b/src/common/Makefile @@ -1,4 +1,4 @@ -txt sql all: core.o socket.o timer.o grfio.o db.o lock.o nullpo.o malloc.o +txt sql all: core.o socket.o timer.o grfio.o db.o lock.o nullpo.o malloc.o mt_rand.o core.o: core.c core.h socket.o: socket.c socket.h mmo.h @@ -8,6 +8,7 @@ db.o: db.c db.h lock.o: lock.h nullpo.o: nullpo.c nullpo.h malloc.o: malloc.c malloc.h +mt_rand.o: mt_rand.c mt_rand.h clean: rm -f *.o diff --git a/src/common/core.c b/src/common/core.c index 2546f4e..94a754b 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -7,11 +7,13 @@ #include <unistd.h> #endif #include <signal.h> +#include <wait.h> #include "core.h" #include "socket.h" #include "timer.h" #include "version.h" +#include "mt_rand.h" #ifdef MEMWATCH #include "memwatch.h" @@ -48,6 +50,9 @@ static void sig_proc(int sn) } exit(0); break; + case SIGCHLD: + wait(&i); + break; } } @@ -129,13 +134,16 @@ int main(int argc,char **argv) { int next; + mt_seed(time(NULL) ^ getpid() ^ getppid()); + Net_Init(); do_socket(); compat_signal(SIGPIPE,SIG_IGN); compat_signal(SIGTERM,sig_proc); compat_signal(SIGINT,sig_proc); - + compat_signal(SIGCHLD,sig_proc); + // Signal to create coredumps by system when necessary (crash) compat_signal(SIGSEGV, SIG_DFL); #ifndef LCCWIN32 diff --git a/src/common/lock.c b/src/common/lock.c index 67001f9..42bbff0 100644 --- a/src/common/lock.c +++ b/src/common/lock.c @@ -1,4 +1,5 @@ +#include <unistd.h> #include <stdio.h> #include "lock.h" #include "socket.h" @@ -10,13 +11,13 @@ FILE* lock_fopen(const char* filename,int *info) { char newfile[512]; FILE *fp; - int no = 0; + int no = getpid(); // 安全なファイル名を得る(手抜き) do { - sprintf(newfile,"%s_%04d.tmp",filename,++no); - } while((fp = fopen_(newfile,"r")) && (fclose_(fp), no<9999) ); - *info = no; + sprintf(newfile,"%s_%d.tmp",filename,no++); + } while((fp = fopen_(newfile,"r")) && fclose_(fp)); + *info = --no; return fopen_(newfile,"w"); } @@ -26,7 +27,7 @@ int lock_fclose(FILE *fp,const char* filename,int *info) { char newfile[512]; if(fp != NULL) { ret = fclose_(fp); - sprintf(newfile,"%s_%04d.tmp",filename,*info); + sprintf(newfile,"%s_%d.tmp",filename,*info); remove(filename); // このタイミングで落ちると最悪。 rename(newfile,filename); diff --git a/src/common/mt_rand.c b/src/common/mt_rand.c new file mode 100644 index 0000000..ab733ae --- /dev/null +++ b/src/common/mt_rand.c @@ -0,0 +1,110 @@ +/* +// This is the ``Mersenne Twister'' random number generator MT19937, which +// generates pseudorandom integers uniformly distributed in 0..(2^32 - 1) +// starting from any odd seed in 0..(2^32 - 1). This version is a recode +// by Shawn Cokus (Cokus@math.washington.edu) on March 8, 1998 of a version by +// Takuji Nishimura (who had suggestions from Topher Cooper and Marc Rieffel in +// July-August 1997). +// +// Effectiveness of the recoding (on Goedel2.math.washington.edu, a DEC Alpha +// running OSF/1) using GCC -O3 as a compiler: before recoding: 51.6 sec. to +// generate 300 million random numbers; after recoding: 24.0 sec. for the same +// (i.e., 46.5% of original time), so speed is now about 12.5 million random +// number generations per second on this machine. +// +// According to the URL <http://www.math.keio.ac.jp/~matumoto/emt.html> +// (and paraphrasing a bit in places), the Mersenne Twister is ``designed +// with consideration of the flaws of various existing generators,'' has +// a period of 2^19937 - 1, gives a sequence that is 623-dimensionally +// equidistributed, and ``has passed many stringent tests, including the +// die-hard test of G. Marsaglia and the load test of P. Hellekalek and +// S. Wegenkittl.'' It is efficient in memory usage (typically using 2506 +// to 5012 bytes of static data, depending on data type sizes, and the code +// is quite short as well). It generates random numbers in batches of 624 +// at a time, so the caching and pipelining of modern systems is exploited. +// It is also divide- and mod-free. +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published by +// the Free Software Foundation (either version 2 of the License or, at your +// option, any later version). This library is distributed in the hope that +// it will be useful, but WITHOUT ANY WARRANTY, without even the implied +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +// the GNU Library General Public License for more details. You should have +// received a copy of the GNU Library General Public License along with this +// library; if not, write to the Free Software Foundation, Inc., 59 Temple +// Place, Suite 330, Boston, MA 02111-1307, USA. +// +// The code as Shawn received it included the following notice: +// +// Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. When +// you use this, send an e-mail to <matumoto@math.keio.ac.jp> with +// an appropriate reference to your work. +// +// It would be nice to CC: <Cokus@math.washington.edu> when you write. +// +*/ + +#include <time.h> +#include "mt_rand.h" + +#define N (624) /* length of state vector */ +#define M (397) /* a period parameter */ +#define K (0x9908B0DFU) /* a magic constant */ +#define hiBit(u) ((u) & 0x80000000U) /* mask all but highest bit of u */ +#define loBit(u) ((u) & 0x00000001U) /* mask all but lowest bit of u */ +#define loBits(u) ((u) & 0x7FFFFFFFU) /* mask the highest bit of u */ +#define mixBits(u, v) (hiBit(u)|loBits(v)) /* move hi bit of u to hi bit of v */ + +static unsigned long state[N+1]; /* state vector + 1 extra to not violate ANSI C */ +static unsigned long *next; /* next random value is computed from here */ +static int left = -1; /* can *next++ this many times before reloading */ + + +void mt_seed(unsigned long seed) +{ + register unsigned long x = (seed | 1U) & 0xFFFFFFFFU, *s = state; + register int j; + + for(left=0, *s++=x, j=N; --j; + *s++ = (x*=69069U) & 0xFFFFFFFFU); +} + + +unsigned long mt_reload(void) +{ + register unsigned long *p0=state, *p2=state+2, *pM=state+M, s0, s1; + register int j; + + if(left < -1) + mt_seed(time(NULL)); + + left=N-1, next=state+1; + + for(s0=state[0], s1=state[1], j=N-M+1; --j; s0=s1, s1=*p2++) + *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); + + for(pM=state, j=M; --j; s0=s1, s1=*p2++) + *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); + + s1=state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); + s1 ^= (s1 >> 11); + s1 ^= (s1 << 7) & 0x9D2C5680U; + s1 ^= (s1 << 15) & 0xEFC60000U; + return(s1 ^ (s1 >> 18)); +} + + +unsigned long mt_random(void) +{ + unsigned long y; + + if(--left < 0) + return(mt_reload()); + + y = *next++; + y ^= (y >> 11); + y ^= (y << 7) & 0x9D2C5680U; + y ^= (y << 15) & 0xEFC60000U; + return(y ^ (y >> 18)); +} diff --git a/src/common/mt_rand.h b/src/common/mt_rand.h new file mode 100644 index 0000000..07f6ef0 --- /dev/null +++ b/src/common/mt_rand.h @@ -0,0 +1,8 @@ +#ifndef __mt_rand_h +#define __mt_rand_h + +void mt_seed(unsigned long seed); +unsigned long mt_reload(void); +unsigned long mt_random(void); + +#endif /* __mt_rand_h */ diff --git a/src/common/utils.h b/src/common/utils.h index 794a0b6..0b006c3 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -1,3 +1,4 @@ +#include "mt_rand.h" #ifndef NULL #define NULL (void *)0 @@ -33,10 +34,9 @@ /* * ModuloRand and ModuloPlusRand. These macros are used to replace the - * vast number of calls to rand()%mod which is low-order bits. These - * instead use the high-order bits as suggested in the man page of rand(). + * vast number of calls to rand()%mod .. * MRAND(10), returns 0-9. * MPRAND(5,10) returns 5-14. */ -#define MRAND(mod) (int) ((float)mod * (rand() / (RAND_MAX + 1.0))) +#define MRAND(mod) (int) (mt_random() % mod) #define MPRAND(add, mod) add + MRAND(mod) diff --git a/src/ladmin/GNUmakefile b/src/ladmin/GNUmakefile index 768626f..bed7b6b 100644 --- a/src/ladmin/GNUmakefile +++ b/src/ladmin/GNUmakefile @@ -2,8 +2,8 @@ all: ladmin txt: ladmin sql: ladmin -COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/malloc.o -COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/db.h ../common/malloc.h +COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/malloc.o ../common/mt_rand.o +COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/db.h ../common/malloc.h ../common/mt_rand.h ladmin: ladmin.o md5calc.o $(COMMON_OBJ) $(CC) -o ../../$@ ladmin.o md5calc.o $(COMMON_OBJ) diff --git a/src/ladmin/Makefile b/src/ladmin/Makefile index 768626f..bed7b6b 100644 --- a/src/ladmin/Makefile +++ b/src/ladmin/Makefile @@ -2,8 +2,8 @@ all: ladmin txt: ladmin sql: ladmin -COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/malloc.o -COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/db.h ../common/malloc.h +COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/malloc.o ../common/mt_rand.o +COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/db.h ../common/malloc.h ../common/mt_rand.h ladmin: ladmin.o md5calc.o $(COMMON_OBJ) $(CC) -o ../../$@ ladmin.o md5calc.o $(COMMON_OBJ) diff --git a/src/login/Makefile b/src/login/Makefile index d807238..0411129 100644 --- a/src/login/Makefile +++ b/src/login/Makefile @@ -1,8 +1,8 @@ all: login-server txt: login-server -COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/lock.o ../common/malloc.o -COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/db.h ../common/lock.h ../common/malloc.h +COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/db.o ../common/lock.o ../common/malloc.o ../common/mt_rand.o +COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h ../common/version.h ../common/db.h ../common/lock.h ../common/malloc.h ../common/mt_rand.h login-server: login.o md5calc.o $(COMMON_OBJ) $(CC) -o ../../$@ login.o md5calc.o $(COMMON_OBJ) diff --git a/src/login/login.c b/src/login/login.c index 6c4ca82..b44eb19 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -25,6 +25,7 @@ #include "version.h" #include "db.h" #include "lock.h" +#include "mt_rand.h" #ifdef PASSWORDENC #include "md5calc.h" @@ -1153,8 +1154,8 @@ int mmo_auth(struct mmo_account* account, int fd) { sprintf(tmpstr + strlen(tmpstr), ".%03d", (int)tv.tv_usec / 1000); account->account_id = auth_dat[i].account_id; - account->login_id1 = rand(); - account->login_id2 = rand(); + account->login_id1 = mt_random(); + account->login_id2 = mt_random(); memcpy(account->lastlogin, auth_dat[i].lastlogin, 24); memcpy(auth_dat[i].lastlogin, tmpstr, 24); account->sex = auth_dat[i].sex; @@ -3785,8 +3786,6 @@ int do_init(int argc, char **argv) { save_config_in_log(); // not before, because log file name can be changed login_lan_config_read((argc > 1) ? argv[1] : LAN_CONF_NAME); - srand(time(NULL)); - for(i = 0; i< AUTH_FIFO_SIZE; i++) auth_fifo[i].delflag = 1; for(i = 0; i < MAX_SERVERS; i++) diff --git a/src/map/Makefile b/src/map/Makefile index f02d43f..7fe6876 100644 --- a/src/map/Makefile +++ b/src/map/Makefile @@ -8,7 +8,7 @@ txt: obj map-server obj: mkdir obj -COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/grfio.o ../common/db.o ../common/lock.o ../common/nullpo.o ../common/malloc.o +COMMON_OBJ = ../common/core.o ../common/socket.o ../common/timer.o ../common/grfio.o ../common/db.o ../common/lock.o ../common/nullpo.o ../common/malloc.o ../common/mt_rand.o LIBS = -lz -lm map-server: obj/tmw.o obj/magic-interpreter-lexer.o obj/magic-interpreter-parser.o obj/magic-interpreter-base.o obj/magic-expr.o obj/magic-stmt.o obj/magic.o obj/map.o obj/chrif.o obj/clif.o obj/pc.o obj/npc.o obj/chat.o obj/path.o obj/itemdb.o obj/mob.o obj/script.o obj/storage.o obj/skill.o obj/atcommand.o obj/battle.o obj/intif.o obj/trade.o obj/party.o obj/guild.o $(COMMON_OBJ) diff --git a/src/map/atcommand.c b/src/map/atcommand.c index eb37561..ed213b2 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -40,6 +40,7 @@ static char command_symbol = '@'; // first char of the commands (by [Yor]) static char msg_table[1000][1024]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others) #define ATCOMMAND_FUNC(x) int atcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message) +ATCOMMAND_FUNC(setup); ATCOMMAND_FUNC(broadcast); ATCOMMAND_FUNC(localbroadcast); ATCOMMAND_FUNC(charwarp); @@ -212,6 +213,7 @@ ATCOMMAND_FUNC(wgm); // First char of commands is configured in atcommand_athena.conf. Leave @ in this list for default value. // to set default level, read atcommand_athena.conf first please. static AtCommandInfo atcommand_info[] = { + { AtCommand_Setup, "@setup", 40, atcommand_setup }, { AtCommand_CharWarp, "@charwarp", 60, atcommand_charwarp }, { AtCommand_Warp, "@warp", 40, atcommand_warp }, { AtCommand_Where, "@where", 1, atcommand_where }, @@ -542,13 +544,27 @@ int get_atcommand_level(const AtCommandType type) { /*======================================== * At-command logging */ +void log_atcommand(struct map_session_data *sd, const char *fmt, ...) { + char message[512]; + va_list ap; -int last_logfile_nr = 0; -char *gm_logfile_name = NULL; -static FILE *gm_logfile = NULL; + va_start(ap, fmt); + vsnprintf(message, 511, fmt, ap); + va_end(ap); -void log_atcommand(struct map_session_data *sd, const char *fmt, ...) -{ + if (pc_isGM(sd)) + gm_log("%s(%d,%d) %s : %s", map[sd->bl.m].name, sd->bl.x, + sd->bl.y, sd->status.name, message); +} + +char *gm_logfile_name = NULL; +/*========================================== + * Log a timestamped line to GM log file + *------------------------------------------ + */ +void gm_log(const char *fmt, ...) { + static int last_logfile_nr = 0; + static FILE *gm_logfile = NULL; time_t time_v; struct tm ctime; int month, year, logfile_nr; @@ -586,16 +602,14 @@ void log_atcommand(struct map_session_data *sd, const char *fmt, ...) last_logfile_nr = logfile_nr; } - if (gm_logfile && pc_isGM(sd)) { - fprintf(gm_logfile, "[%04d-%02d-%02d %02d:%02d:%02d] %s(%d,%d) %s : %s\n", - year, month, ctime.tm_mday, - ctime.tm_hour, ctime.tm_min, ctime.tm_sec, - map[sd->bl.m].name, sd->bl.x, sd->bl.y, sd->status.name, - message); - fflush(gm_logfile); - } + fprintf(gm_logfile, "[%04d-%02d-%02d %02d:%02d:%02d] %s\n", + year, month, ctime.tm_mday, ctime.tm_hour, + ctime.tm_min, ctime.tm_sec, message); + + fflush(gm_logfile); } + /*========================================== *is_atcommand @コマンドに存在するかどうか確認する *------------------------------------------ @@ -814,6 +828,43 @@ int atcommand_config_read(const char *cfgName) { */ /*========================================== + * @setup - Safely set a chars levels and warp them to a special place + * TAW Specific + *------------------------------------------ + */ +int atcommand_setup( + const int fd, struct map_session_data* sd, + const char* command, const char* message) +{ + char buf[256]; + char character[100]; + int level = 1; + + memset(character, '\0', sizeof(character)); + + if (!message || !*message || sscanf(message, "%d %99[^\n]", &level, character) < 2) { + clif_displaymessage(fd, "Usage: @setup <level> <char name>"); + return -1; + } + level--; + + snprintf(buf, 255, "-255 %s", character); + atcommand_character_baselevel(fd, sd, "@charbaselvl", buf); + + snprintf(buf, 255, "%d %s", level, character); + atcommand_character_baselevel(fd, sd, "@charbaselvl", buf); + + snprintf(buf, 255, "+10 %s", character); + atcommand_character_joblevel(fd, sd, "@charjoblvl", buf); + + snprintf(buf, 255, "018-1.gat 24 98 %s", character); + atcommand_charwarp(fd, sd, "@charwarp", buf); + + return(0); + +} + +/*========================================== * @rura+ *------------------------------------------ */ @@ -836,9 +887,9 @@ int atcommand_charwarp( } if (x <= 0) - x = rand() % 399 + 1; + x = MRAND(399) + 1; if (y <= 0) - y = rand() % 399 + 1; + y = MRAND(399) + 1; if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) strcat(map_name, ".gat"); @@ -895,9 +946,9 @@ int atcommand_warp(const int fd, struct map_session_data* sd, const char* comman } if (x <= 0) - x = rand() % 399 + 1; + x = MRAND(399) + 1; if (y <= 0) - y = rand() % 399 + 1; + y = MRAND(399) + 1; if (strstr(map_name, ".gat") == NULL && strstr(map_name, ".afm") == NULL && strlen(map_name) < 13) // 16 - 4 (.gat) strcat(map_name, ".gat"); @@ -1006,9 +1057,9 @@ int atcommand_jump(const int fd, struct map_session_data* sd, const char* comman sscanf(message, "%d %d", &x, &y); if (x <= 0) - x = rand() % 399 + 1; + x = MRAND(399) + 1; if (y <= 0) - y = rand() % 399 + 1; + y = MRAND(399) + 1; if (x > 0 && x < 400 && y > 0 && y < 400) { if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) { clif_displaymessage(fd, "You are not authorised to warp you to your actual map."); @@ -2486,11 +2537,11 @@ int atcommand_spawn(const int fd, struct map_session_data* sd, const char* comma k = 0; while(j++ < 8 && k == 0) { // try 8 times to spawn the monster (needed for close area) if (x <= 0) - mx = sd->bl.x + (rand() % range - (range / 2)); + mx = sd->bl.x + (MRAND(range) - (range / 2)); else mx = x; if (y <= 0) - my = sd->bl.y + (rand() % range - (range / 2)); + my = sd->bl.y + (MRAND(range) - (range / 2)); else my = y; k = mob_once_spawn((struct map_session_data*)sd, "this", mx, my, "", mob_id, 1, ""); @@ -5410,7 +5461,7 @@ int atcommand_jail( if ((pl_sd = map_nick2sd(character)) != NULL) { if (pc_isGM(sd) >= pc_isGM(pl_sd)) { // you can jail only lower or same GM - switch(rand() % 2) { + switch(MRAND(2)) { case 0: x = 24; y = 75; @@ -6771,8 +6822,8 @@ int atcommand_summon(const int fd, struct map_session_data* sd, const char* comm if(mob_id == 0) return -1; - x = sd->bl.x + (rand() % 10 - 5); - y = sd->bl.y + (rand() % 10 - 5); + x = sd->bl.x + (MRAND(10) - 5); + y = sd->bl.y + (MRAND(10) - 5); id = mob_once_spawn(sd,"this", x, y, "--ja--", mob_id, 1, ""); if((md=(struct mob_data *)map_id2bl(id))){ diff --git a/src/map/atcommand.h b/src/map/atcommand.h index 3f247bc..df996b6 100644 --- a/src/map/atcommand.h +++ b/src/map/atcommand.h @@ -7,6 +7,7 @@ enum AtCommandType { AtCommand_None = -1, AtCommand_Broadcast = 0, + AtCommand_Setup, AtCommand_LocalBroadcast, AtCommand_MapMove, AtCommand_ResetState, @@ -213,6 +214,7 @@ int atcommand_config_read(const char *cfgName); int msg_config_read(const char *cfgName); void log_atcommand(struct map_session_data *sd, const char *fmt, ...); +void gm_log(const char *fmt, ...); #endif diff --git a/src/map/battle.c b/src/map/battle.c index c21d69c..e424ef9 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -18,6 +18,7 @@ #include "pc.h" #include "skill.h" #include "../common/socket.h" +#include "mt_rand.h" #ifdef MEMWATCH #include "memwatch.h" diff --git a/src/map/clif.c b/src/map/clif.c index 5a372e7..70311e9 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -3369,9 +3369,9 @@ int clif_damage(struct block_list *src,struct block_list *dst,unsigned int tick, type = 9; if(sc_data[SC_HALLUCINATION].timer != -1) { if(damage > 0) - damage = damage*(5+sc_data[SC_HALLUCINATION].val1) + rand()%100; + damage = damage*(5+sc_data[SC_HALLUCINATION].val1) + MRAND(100); if(damage2 > 0) - damage2 = damage2*(5+sc_data[SC_HALLUCINATION].val1) + rand()%100; + damage2 = damage2*(5+sc_data[SC_HALLUCINATION].val1) + MRAND(100); } } @@ -3881,7 +3881,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst, if(type != 5 && sc_data[SC_ENDURE].timer != -1) type = 9; if(sc_data[SC_HALLUCINATION].timer != -1 && damage > 0) - damage = damage*(5+sc_data[SC_HALLUCINATION].val1) + rand()%100; + damage = damage*(5+sc_data[SC_HALLUCINATION].val1) + MRAND(100); } WBUFW(buf,0)=0x1de; @@ -3921,7 +3921,7 @@ int clif_skill_damage2(struct block_list *src,struct block_list *dst, if(type != 5 && sc_data[SC_ENDURE].timer != -1) type = 9; if(sc_data[SC_HALLUCINATION].timer != -1 && damage > 0) - damage = damage*(5+sc_data[SC_HALLUCINATION].val1) + rand()%100; + damage = damage*(5+sc_data[SC_HALLUCINATION].val1) + MRAND(100); } WBUFW(buf,0)=0x115; @@ -6506,7 +6506,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data *sd) { // S 008c < if (tmw_CheckChatSpam(sd, RFIFOP(fd,4))) return; - if ((malformed)||(pc_isdead(sd))) { + if (malformed) { free(buf); return; } diff --git a/src/map/map.c b/src/map/map.c index b1ac9e3..cf50dfc 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -709,7 +709,7 @@ int map_searchrandfreecell(int m,int x,int y,int range) { } if(free_cell==0) return -1; - free_cell=rand()%free_cell; + free_cell=MRAND(free_cell); for(i=-range;i<=range;i++){ if(i+y<0 || i+y>=map[m].ys) continue; @@ -750,7 +750,7 @@ int map_addflooritem_any(struct item *item_data, int amount, int m, int x, int y if((xy=map_searchrandfreecell(m,x,y, dispersal))<0) return 0; - r=rand(); + r=mt_random(); fitem = (struct flooritem_data *)aCalloc(1,sizeof(*fitem)); fitem->bl.type=BL_ITEM; @@ -1833,8 +1833,6 @@ int do_init(int argc, char *argv[]) { unsigned char *MSG_CONF_NAME = "conf/msg_athena.conf"; unsigned char *GRF_PATH_FILENAME = "conf/grf-files.txt"; - srand(gettick()); - for (i = 1; i < argc ; i++) { if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "--h") == 0 || strcmp(argv[i], "--?") == 0 || strcmp(argv[i], "/?") == 0) diff --git a/src/map/map.h b/src/map/map.h index ad6575a..c4e914f 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -356,7 +356,9 @@ struct map_session_data { short sg_count; time_t chat_reset_due; + time_t chat_repeat_reset_due; int chat_lines_in; + int chat_total_repeats; char chat_lastmsg[513]; time_t trade_reset_due; diff --git a/src/map/pc.c b/src/map/pc.c index 6f1cc86..34cb59a 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -571,7 +571,7 @@ int pc_breakweapon(struct map_session_data *sd) if(sd==NULL) return -1; - if(sd->unbreakable>=rand()%100) + if(sd->unbreakable>=MRAND(100)) return 0; if(sd->sc_data && sd->sc_data[SC_CP_WEAPON].timer != -1) return 0; @@ -608,7 +608,7 @@ int pc_breakarmor(struct map_session_data *sd) if(sd==NULL) return -1; - if(sd->unbreakable>=rand()%100) + if(sd->unbreakable>=MRAND(100)) return 0; if(sd->sc_data && sd->sc_data[SC_CP_ARMOR].timer != -1) return 0; @@ -816,11 +816,10 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, short tmw_versio } } - sd->chat_reset_due = sd->chat_lines_in = 0; + // Initialize antispam vars + sd->chat_reset_due = sd->chat_lines_in = sd->chat_total_repeats = sd->chat_repeat_reset_due = 0; sd->chat_lastmsg[0] = '\0'; - sd->trade_reset_due = sd->trades_in = 0; - sd->sit_reset_due = sd->sits_in = 0; // message of the limited time of the account @@ -3400,8 +3399,8 @@ int pc_steal_coin(struct map_session_data *sd,struct block_list *bl) if(md && !md->state.steal_coin_flag && md->sc_data && md->sc_data[SC_STONE].timer == -1 && md->sc_data[SC_FREEZE].timer == -1) { skill = pc_checkskill(sd,RG_STEALCOIN)*10; rate = skill + (sd->status.base_level - mob_db[md->class].lv)*3 + sd->paramc[4]*2 + sd->paramc[5]*2; - if(rand()%1000 < rate) { - pc_getzeny(sd,mob_db[md->class].lv*10 + rand()%100); + if(MRAND(1000) < rate) { + pc_getzeny(sd,mob_db[md->class].lv*10 + MRAND(100)); md->state.steal_coin_flag = 1; return 1; } @@ -3516,8 +3515,8 @@ int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrt printf("stacked (%d,%d)\n",x,y); } do { - x=rand()%(map[m].xs-2)+1; - y=rand()%(map[m].ys-2)+1; + x=MRAND(map[m].xs-2)+1; + y=MRAND(map[m].ys-2)+1; } while((c=read_gat(m,x,y))==1 || c==5); } @@ -3564,8 +3563,8 @@ int pc_randomwarp(struct map_session_data *sd, int type) { return 0; do{ - x=rand()%(map[m].xs-2)+1; - y=rand()%(map[m].ys-2)+1; + x=MRAND(map[m].xs-2)+1; + y=MRAND(map[m].ys-2)+1; } while (((c=read_gat(m,x,y)) == 1 || c == 5) && (i++) < 1000); if (i < 1000) @@ -5100,8 +5099,8 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage) } } if(eq_num > 0){ - int n = eq_n[rand()%eq_num];//ソスYソスソスソスAソスCソスeソスソスソスフ抵ソスソスソスソス辜会ソスソスソス_ソスソス - if(rand()%10000 < per){ + int n = eq_n[MRAND(eq_num)];//ソスYソスソスソスAソスCソスeソスソスソスフ抵ソスソスソスソス辜会ソスソスソス_ソスソス + if(MRAND(10000) < per){ if(sd->status.inventory[n].equip) pc_unequipitem(sd,n,0); pc_dropitem(sd,n,1); @@ -5111,7 +5110,7 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage) else if(id > 0){ for(i=0;i<MAX_INVENTORY;i++){ if(sd->status.inventory[i].nameid == id//ItemIDソスソスソスソスソスvソスソスソストゑソスソスソス - && rand()%10000 < per//ソスhソスソスソスbソスvソスソスソスソスソスソスソスソスOKソスソス + && MRAND(10000) < per//ソスhソスソスソスbソスvソスソスソスソスソスソスソスソスOKソスソス && ((type == 1 && !sd->status.inventory[i].equip)//ソス^ソスCソスvソスソスソスソスソスソスOKソスネゑソスソスhソスソスソスbソスv || (type == 2 && sd->status.inventory[i].equip) || type == 3) ){ diff --git a/src/map/skill.c b/src/map/skill.c index c661dc2..778acea 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -943,13 +943,13 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s case 0: /* 通常攻撃 */ /* 自動鷹 */ if( sd && pc_isfalcon(sd) && sd->status.weapon == 11 && (skill=pc_checkskill(sd,HT_BLITZBEAT))>0 && - rand()%1000 <= sd->paramc[5]*10/3+1 ) { + MRAND(1000) <= sd->paramc[5]*10/3+1 ) { int lv=(sd->status.job_level+9)/10; skill_castend_damage_id(src,bl,HT_BLITZBEAT,(skill<lv)?skill:lv,tick,0xf00000); } // スナッチャー if(sd && sd->status.weapon != 11 && (skill=pc_checkskill(sd,RG_SNATCHER)) > 0) - if((skill*15 + 55) + (skill2 = pc_checkskill(sd,TF_STEAL))*10 > rand()%1000) { + if((skill*15 + 55) + (skill2 = pc_checkskill(sd,TF_STEAL))*10 > MRAND(1000)) { if(pc_steal_item(sd,bl)) clif_skill_nodamage(src,bl,TF_STEAL,skill2,1); else @@ -959,14 +959,14 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s case SM_BASH: /* バッシュ(急所攻撃) */ if( sd && (skill=pc_checkskill(sd,SM_FATALBLOW))>0 ){ - if( rand()%100 < 6*(skilllv-5)*sc_def_vit/100 ) + if(MRAND(100) < 6*(skilllv-5)*sc_def_vit/100 ) skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(SM_FATALBLOW,skilllv),0); } break; case TF_POISON: /* インベナム */ case AS_SPLASHER: /* ベナムスプラッシャー */ - if(rand()%100< (2*skilllv+10)*sc_def_vit/100 ) + if(MRAND(100) < (2*skilllv+10)*sc_def_vit/100 ) skill_status_change_start(bl,SC_POISON,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); else{ if(sd && skillid==TF_POISON) @@ -975,14 +975,14 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s break; case AS_SONICBLOW: /* ソニックブロー */ - if( rand()%100 < (2*skilllv+10)*sc_def_vit/100 ) + if(MRAND(100) < (2*skilllv+10)*sc_def_vit/100 ) skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case HT_FREEZINGTRAP: /* フリージングトラップ */ rate=skilllv*3+35; - if(rand()%100 < rate*sc_def_mdef/100) + if(MRAND(100) < rate*sc_def_mdef/100) skill_status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; @@ -990,7 +990,7 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s case WZ_FROSTNOVA: /* フロストノヴァ */ rate=(skilllv*3+35)*sc_def_mdef/100-(battle_get_int(bl)+battle_get_luk(bl))/15; rate=rate<=5?5:rate; - if(rand()%100 < rate) + if(MRAND(100) < rate) skill_status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); else if(sd) clif_skill_fail(sd,skillid,0,0); @@ -1008,7 +1008,7 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s break; case HT_LANDMINE: /* ランドマイン */ - if( rand()%100 < (5*skilllv+30)*sc_def_vit/100 ) + if( MRAND(100) < (5*skilllv+30)*sc_def_vit/100 ) skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; @@ -1019,62 +1019,62 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s } break; case HT_SANDMAN: /* サンドマン */ - if( rand()%100 < (5*skilllv+30)*sc_def_int/100 ) + if( MRAND(100) < (5*skilllv+30)*sc_def_int/100 ) skill_status_change_start(bl,SC_SLEEP,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case TF_SPRINKLESAND: /* 砂まき */ - if( rand()%100 < 15*sc_def_int/100 ) + if( MRAND(100) < 15*sc_def_int/100 ) skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case TF_THROWSTONE: /* 石投げ */ - if( rand()%100 < 5*sc_def_vit/100 ) + if( MRAND(100) < 5*sc_def_vit/100 ) skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case CR_HOLYCROSS: /* ホーリークロス */ - if( rand()%100 < 3*skilllv*sc_def_int/100 ) + if( MRAND(100) < 3*skilllv*sc_def_int/100 ) skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case CR_GRANDCROSS: /* グランドクロス */ { int race = battle_get_race(bl); - if( (battle_check_undead(race,battle_get_elem_type(bl)) || race == 6) && rand()%100 < 100000*sc_def_int/100) //強制付与だが完全耐性には無効 + if( (battle_check_undead(race,battle_get_elem_type(bl)) || race == 6) && MRAND(100) < 100000*sc_def_int/100) //強制付与だが完全耐性には無効 skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); } break; case CR_SHIELDCHARGE: /* シールドチャージ */ - if( rand()%100 < (15 + skilllv*5)*sc_def_vit/100 ) + if( MRAND(100) < (15 + skilllv*5)*sc_def_vit/100 ) skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case RG_RAID: /* サプライズアタック */ - if( rand()%100 < (10+3*skilllv)*sc_def_vit/100 ) + if( MRAND(100) < (10+3*skilllv)*sc_def_vit/100 ) skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - if( rand()%100 < (10+3*skilllv)*sc_def_int/100 ) + if( MRAND(100) < (10+3*skilllv)*sc_def_int/100 ) skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case BA_FROSTJOKE: - if(rand()%100 < (15+5*skilllv)*sc_def_mdef/100) + if(MRAND(100) < (15+5*skilllv)*sc_def_mdef/100) skill_status_change_start(bl,SC_FREEZE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case DC_SCREAM: - if( rand()%100 < (25+5*skilllv)*sc_def_vit/100 ) + if( MRAND(100) < (25+5*skilllv)*sc_def_vit/100 ) skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case BD_LULLABY: /* 子守唄 */ - if( rand()%100 < 15*sc_def_int/100 ) + if( MRAND(100) < 15*sc_def_int/100 ) skill_status_change_start(bl,SC_SLEEP,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; /* MOBの追加効果付きスキル */ case NPC_PETRIFYATTACK: - if(rand()%100 < sc_def_mdef) + if(MRAND(100) < sc_def_mdef) skill_status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case NPC_POISON: @@ -1084,12 +1084,12 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s skill_status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skilllv,0); break; case NPC_CURSEATTACK: - if(rand()%100 < sc_def_luk) + if(MRAND(100) < sc_def_luk) skill_status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case NPC_SLEEPATTACK: case NPC_BLINDATTACK: - if(rand()%100 < sc_def_int) + if(MRAND(100) < sc_def_int) skill_status_change_start(bl,sc[skillid-NPC_POISON],skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case NPC_MENTALBREAKER: @@ -1103,43 +1103,43 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s // -- moonsoul (adding status effect chance given to wizard aoe skills meteor and vermillion) // case WZ_METEOR: - if(rand()%100 < sc_def_vit) + if(MRAND(100) < sc_def_vit) skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case WZ_VERMILION: - if(rand()%100 < sc_def_int) + if(MRAND(100) < sc_def_int) skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; // -- moonsoul (stun ability of new champion skill tigerfist) // case CH_TIGERFIST: - if( rand()%100 < (5 + skilllv*5)*sc_def_vit/100 ) + if( MRAND(100) < (5 + skilllv*5)*sc_def_vit/100 ) skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case LK_SPIRALPIERCE: - if( rand()%100 < (15 + skilllv*5)*sc_def_vit/100 ) + if( MRAND(100) < (15 + skilllv*5)*sc_def_vit/100 ) skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case ST_REJECTSWORD: /* フリージングトラップ */ - if( rand()%100 < (10 + skilllv*5) ) + if( MRAND(100) < (10 + skilllv*5) ) skill_status_change_start(bl,SC_AUTOCOUNTER,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case PF_FOGWALL: /* ホーリークロス */ - if( rand()%100 < 3*skilllv*sc_def_int/100 ) + if( MRAND(100) < 3*skilllv*sc_def_int/100 ) skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case LK_HEADCRUSH: /* ヘッドクラッシュ */ {//条件が良く分からないので適当に int race=battle_get_race(bl); - if( !(battle_check_undead(race,battle_get_elem_type(bl)) || race == 6) && rand()%100 < (2*skilllv+10)*sc_def_vit/100 ) + if( !(battle_check_undead(race,battle_get_elem_type(bl)) || race == 6) && MRAND(100) < (2*skilllv+10)*sc_def_vit/100 ) skill_status_change_start(bl,SC_HEADCRUSH,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); } break; case LK_JOINTBEAT: /* ジョイントビート */ //条件が良く分からないので適当に - if( rand()%100 < (2*skilllv+10)*sc_def_vit/100 ) + if( MRAND(100) < (2*skilllv+10)*sc_def_vit/100 ) skill_status_change_start(bl,SC_JOINTBEAT,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case PF_SPIDERWEB: /* スパイダーウェッブ */ @@ -1152,9 +1152,9 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s } break; case ASC_METEORASSAULT: /* メテオアサルト */ - if( rand()%100 < (15 + skilllv*5)*sc_def_vit/100 ) //状態異常は詳細が分からないので適当に + if( MRAND(100) < (15 + skilllv*5)*sc_def_vit/100 ) //状態異常は詳細が分からないので適当に skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); - if( rand()%100 < (10+3*skilllv)*sc_def_int/100 ) + if( MRAND(100) < (10+3*skilllv)*sc_def_int/100 ) skill_status_change_start(bl,SC_BLIND,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; case MO_EXTREMITYFIST: /* 阿修羅覇凰拳 */ @@ -1179,14 +1179,14 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s sc_def_card=sc_def_luk; if(!sd->state.arrow_atk) { - if(rand()%10000 < (sd->addeff[i-SC_STONE])*sc_def_card/100 ){ + if(MRAND(10000) < (sd->addeff[i-SC_STONE])*sc_def_card/100 ){ if(battle_config.battle_log) printf("PC %d skill_addeff: cardによる異常発動 %d %d\n",sd->bl.id,i,sd->addeff[i-SC_STONE]); skill_status_change_start(bl,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0); } } else { - if(rand()%10000 < (sd->addeff[i-SC_STONE]+sd->arrow_addeff[i-SC_STONE])*sc_def_card/100 ){ + if(MRAND(10000) < (sd->addeff[i-SC_STONE]+sd->arrow_addeff[i-SC_STONE])*sc_def_card/100 ){ if(battle_config.battle_log) printf("PC %d skill_addeff: cardによる異常発動 %d %d\n",sd->bl.id,i,sd->addeff[i-SC_STONE]); skill_status_change_start(bl,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0); @@ -1203,14 +1203,14 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s sc_def_card=sc_def_luk2; if(!sd->state.arrow_atk) { - if(rand()%10000 < (sd->addeff2[i-SC_STONE])*sc_def_card/100 ){ + if(MRAND(10000) < (sd->addeff2[i-SC_STONE])*sc_def_card/100 ){ if(battle_config.battle_log) printf("PC %d skill_addeff: cardによる異常発動 %d %d\n",src->id,i,sd->addeff2[i-SC_STONE]); skill_status_change_start(src,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0); } } else { - if(rand()%10000 < (sd->addeff2[i-SC_STONE]+sd->arrow_addeff2[i-SC_STONE])*sc_def_card/100 ){ + if(MRAND(10000) < (sd->addeff2[i-SC_STONE]+sd->arrow_addeff2[i-SC_STONE])*sc_def_card/100 ){ if(battle_config.battle_log) printf("PC %d skill_addeff: cardによる異常発動 %d %d\n",src->id,i,sd->addeff2[i-SC_STONE]); skill_status_change_start(src,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0); @@ -1564,7 +1564,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds int s_lv = battle_get_lv(src),t_lv = battle_get_lv(bl); int rate = 50 + skilllv * 5; rate = rate + (s_lv - t_lv); - if(rand()%100 < rate) + if(MRAND(100) < rate) skill_addtimerskill(src,tick + 800,bl->id,0,0,skillid,skilllv,0,flag); } if(damage > 0 && dmg.flag&BF_SKILL && bl->type==BL_PC && pc_checkskill((struct map_session_data *)bl,RG_PLAGIARISM)){ @@ -1617,22 +1617,22 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds struct map_session_data *sd = (struct map_session_data *)src; int hp = 0,sp = 0; nullpo_retr(0, sd); - if(sd->hp_drain_rate && sd->hp_drain_per > 0 && dmg.damage > 0 && rand()%100 < sd->hp_drain_rate) { + if(sd->hp_drain_rate && sd->hp_drain_per > 0 && dmg.damage > 0 && MRAND(100) < sd->hp_drain_rate) { hp += (dmg.damage * sd->hp_drain_per)/100; if(sd->hp_drain_rate > 0 && hp < 1) hp = 1; else if(sd->hp_drain_rate < 0 && hp > -1) hp = -1; } - if(sd->hp_drain_rate_ && sd->hp_drain_per_ > 0 && dmg.damage2 > 0 && rand()%100 < sd->hp_drain_rate_) { + if(sd->hp_drain_rate_ && sd->hp_drain_per_ > 0 && dmg.damage2 > 0 && MRAND(100) < sd->hp_drain_rate_) { hp += (dmg.damage2 * sd->hp_drain_per_)/100; if(sd->hp_drain_rate_ > 0 && hp < 1) hp = 1; else if(sd->hp_drain_rate_ < 0 && hp > -1) hp = -1; } - if(sd->sp_drain_rate > 0 && sd->sp_drain_per > 0 && dmg.damage > 0 && rand()%100 < sd->sp_drain_rate) { + if(sd->sp_drain_rate > 0 && sd->sp_drain_per > 0 && dmg.damage > 0 && MRAND(100) < sd->sp_drain_rate) { sp += (dmg.damage * sd->sp_drain_per)/100; if(sd->sp_drain_rate > 0 && sp < 1) sp = 1; else if(sd->sp_drain_rate < 0 && sp > -1) sp = -1; } - if(sd->sp_drain_rate_ > 0 && sd->sp_drain_per_ > 0 && dmg.damage2 > 0 && rand()%100 < sd->sp_drain_rate_) { + if(sd->sp_drain_rate_ > 0 && sd->sp_drain_per_ > 0 && dmg.damage2 > 0 && MRAND(100) < sd->sp_drain_rate_) { sp += (dmg.damage2 * sd->sp_drain_per_)/100; if(sd->sp_drain_rate_ > 0 && sp < 1) sp = 1; else if(sd->sp_drain_rate_ < 0 && sp > -1) sp = -1; @@ -1865,7 +1865,7 @@ static int skill_timerskill(int tid, unsigned int tick, int id,int data ) int x,y,i,j,c; pc_randomwarp(sd,3); for(i=0;i<16;i++) { - j = rand()%8; + j = MRAND(8); x = sd->bl.x + dirx[j]; y = sd->bl.y + diry[j]; if((c=map_getcell(sd->bl.m,x,y)) != 1 && c != 5) @@ -1886,7 +1886,7 @@ static int skill_timerskill(int tid, unsigned int tick, int id,int data ) int x,y,i,j,c; mob_warp(md,-1,-1,-1,3); for(i=0;i<16;i++) { - j = rand()%8; + j = MRAND(8); x = md->bl.x + dirx[j]; y = md->bl.y + diry[j]; if((c=map_getcell(md->bl.m,x,y)) != 1 && c != 5) @@ -2163,7 +2163,7 @@ int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int s case AM_ACIDTERROR: /* アシッドテラー */ skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); - if(bl->type == BL_PC && rand()%100 < skill_get_time(skillid,skilllv) && battle_config.equipment_breaking) + if(bl->type == BL_PC && MRAND(100) < skill_get_time(skillid,skilllv) && battle_config.equipment_breaking) pc_breakarmor((struct map_session_data *)bl); break; case MO_FINGEROFFENSIVE: /* 指弾 */ @@ -2692,7 +2692,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int case AL_DECAGI: /* 速度減少 */ if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage ) break; - if( rand()%100 < (50+skilllv*3+(battle_get_lv(src)+battle_get_int(src)/5)-sc_def_mdef) ) { + if( MRAND(100) < (50+skilllv*3+(battle_get_lv(src)+battle_get_int(src)/5)-sc_def_mdef) ) { clif_skill_nodamage(src,bl,skillid,skilllv,1); skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0); } @@ -2704,7 +2704,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int if(battle_check_target(src,bl,BCT_ENEMY) && (race == 6 || battle_check_undead(race,ele))) { int slv=battle_get_lv(src),tlv=battle_get_lv(bl),rate; rate = 25 + skilllv*2 + slv - tlv; - if(rand()%100 < rate) + if(MRAND(100) < rate) skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,0,0); } } @@ -2726,7 +2726,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int break; if(sc_data && sc_data[SC_DIVINA].timer != -1) skill_status_change_end(bl,SC_DIVINA,-1); - else if( rand()%100 < sc_def_vit ) { + else if( MRAND(100) < sc_def_vit ) { skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,skill_get_time(skillid,skilllv),0); } } @@ -2826,7 +2826,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int break; } } - if(rand()%100 > (75+skilllv*1) && (skilllv != 5)) { + if(MRAND(100) > (75+skilllv*1) && (skilllv != 5)) { clif_skill_fail(sd,skillid,0,0); clif_skill_nodamage(src,bl,skillid,skilllv,0); if(bl->type==BL_PC && battle_config.equipment_breaking) { @@ -3021,7 +3021,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int } }else if(sd && dstmd){ //対象がモンスターの場合 //20%の確率で対象のLv*2のSPを回復する。成功したときはターゲット(σ゚Д゚)σゲッツ!! - if(rand()%100<20){ + if(MRAND(100)<20){ i=2*mob_db[dstmd->class].lv; mob_target(dstmd,src,0); } @@ -3063,7 +3063,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int clif_skill_nodamage(src,bl,skillid,skilllv,1); if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_weapon_damage ) break; - if( rand()%100 < (20+ 10*skilllv)*sc_def_vit/100 ) { + if( MRAND(100) < (20+ 10*skilllv)*sc_def_vit/100 ) { skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); } break; @@ -3318,7 +3318,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int clif_skill_nodamage(src,bl,skillid,skilllv,1); if( bl->type==BL_PC && ((struct map_session_data *)bl)->special_state.no_magic_damage ) break; - if( rand()%100 < skilllv*4+20 && !battle_check_undead(battle_get_race(bl),battle_get_elem_type(bl))) + if( MRAND(100) < skilllv*4+20 && !battle_check_undead(battle_get_race(bl),battle_get_elem_type(bl))) skill_status_change_start(bl,SC_STONE,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); else if(sd) clif_skill_fail(sd,skillid,0,0); @@ -3359,7 +3359,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int int blind_time; //blind_time=30-battle_get_vit(bl)/10-battle_get_int/15; blind_time=30*(100-(battle_get_int(bl)+battle_get_vit(bl))/2)/100; - if(rand()%100 < (100-(battle_get_int(bl)/2+battle_get_vit(bl)/3+battle_get_luk(bl)/10))) + if(MRAND(100) < (100-(battle_get_int(bl)/2+battle_get_vit(bl)/3+battle_get_luk(bl)/10))) skill_status_change_start(bl, SC_BLIND,1,0,0,0,blind_time,0); } if(dstmd){ @@ -3367,7 +3367,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int dstmd->target_id=0; dstmd->state.targettype = NONE_ATTACKABLE; dstmd->state.skillstate=MSS_IDLE; - dstmd->next_walktime=tick+rand()%3000+3000; + dstmd->next_walktime=tick+MRAND(3000)+3000; } } break; @@ -3455,7 +3455,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int break; strip_per = 5+2*skilllv+strip_fix/5; strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; - if(rand()%100 < strip_per){ + if(MRAND(100) < strip_per){ clif_skill_nodamage(src,bl,skillid,skilllv,1); skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,strip_time,0 ); if(dstsd){ @@ -3478,7 +3478,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int break; strip_per = 5+2*skilllv+strip_fix/5; strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; - if(rand()%100 < strip_per){ + if(MRAND(100) < strip_per){ clif_skill_nodamage(src,bl,skillid,skilllv,1); skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,strip_time,0 ); if(dstsd){ @@ -3501,7 +3501,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int break; strip_per = 5+2*skilllv+strip_fix/5; strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; - if(rand()%100 < strip_per){ + if(MRAND(100) < strip_per){ clif_skill_nodamage(src,bl,skillid,skilllv,1); skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,strip_time,0 ); if(dstsd){ @@ -3523,7 +3523,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int break; strip_per = 5+2*skilllv+strip_fix/5; strip_time = skill_get_time(skillid,skilllv)+strip_fix/2; - if(rand()%100 < strip_per){ + if(MRAND(100) < strip_per){ clif_skill_nodamage(src,bl,skillid,skilllv,1); skill_status_change_start(bl,SkillStatusChangeTable[skillid],skilllv,0,0,0,strip_time,0 ); if(dstsd){ @@ -3589,7 +3589,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int } } else { - hp = (1 + rand()%400) * (100 + skilllv*10) / 100; + hp = (1 + MRAND(400)) * (100 + skilllv*10) / 100; hp = hp * (100 + (battle_get_vit(bl)<<1)) / 100; if(dstsd) hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10) / 100; @@ -3768,7 +3768,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int maxlv = skilllv - 4; } else if(skilllv >=2) { - int i = rand()%3; + int i = MRAND(3); spellid = spellarray[i]; maxlv = skilllv - 1; } @@ -3797,8 +3797,8 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int clif_skill_nodamage(src,bl,skillid,skilllv,1); md->def_ele=skill_get_pl(skillid); if(md->def_ele==0) /* ランダム変化、ただし、*/ - md->def_ele=rand()%10; /* 不死属性は除く */ - md->def_ele+=(1+rand()%4)*20; /* 属性レベルはランダム */ + md->def_ele=MRAND(10); /* 不死属性は除く */ + md->def_ele+=(1+MRAND(4))*20; /* 属性レベルはランダム */ } break; @@ -3827,7 +3827,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int break; if(battle_get_elem_type(bl) == 7 || battle_get_race(bl) == 6) break; - if(rand()%100 < sc_def*(50+skilllv*5)/100) { + if(MRAND(100) < sc_def*(50+skilllv*5)/100) { if(dstsd) { int hp = battle_get_hp(bl)-1; pc_heal(dstsd,-hp,0); @@ -3848,7 +3848,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int break; if(dstsd) pc_heal(dstsd,0,-100); - if(rand()%100 < (skilllv*5)*sc_def_vit/100) + if(MRAND(100) < (skilllv*5)*sc_def_vit/100) skill_status_change_start(bl,SC_STAN,skilllv,0,0,0,skill_get_time2(skillid,skilllv),0); break; @@ -4313,8 +4313,8 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil for(i=0;i<2+(skilllv>>1);i++) { int j=0, c; do { - tmpx = x + (rand()%7 - 3); - tmpy = y + (rand()%7 - 3); + tmpx = x + (MRAND(7) - 3); + tmpy = y + (MRAND(7) - 3); if(tmpx < 0) tmpx = 0; else if(tmpx >= map[src->m].xs) @@ -5346,7 +5346,7 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int case 0xb1: /* デモンストレーション */ skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); - if(bl->type == BL_PC && rand()%100 < sg->skill_lv && battle_config.equipment_breaking) + if(bl->type == BL_PC && MRAND(100) < sg->skill_lv && battle_config.equipment_breaking) pc_breakweapon((struct map_session_data *)bl); break; case 0x99: /* トーキーボックス */ @@ -7268,7 +7268,7 @@ int skill_frostjoke_scream(struct block_list *bl,va_list ap) if(battle_check_target(src,bl,BCT_ENEMY) > 0) skill_additional_effect(src,bl,skillnum,skilllv,BF_MISC,tick); else if(battle_check_target(src,bl,BCT_PARTY) > 0) { - if(rand()%100 < 10)//PTメンバにも低確率でかかる(とりあえず10%) + if(MRAND(100) < 10)//PTメンバにも低確率でかかる(とりあえず10%) skill_additional_effect(src,bl,skillnum,skilllv,BF_MISC,tick); } @@ -8274,7 +8274,7 @@ int skill_status_effect(struct block_list *bl, int type, int val1, int val2, int return 0; if(SC_STONE<=type && type<=SC_BLIND){ /* カードによる耐性 */ - if( sd && sd->reseff[type-SC_STONE] > 0 && rand()%10000<sd->reseff[type-SC_STONE]){ + if( sd && sd->reseff[type-SC_STONE] > 0 && MRAND(10000)<sd->reseff[type-SC_STONE]){ if(battle_config.battle_log) printf("PC %d skill_sc_start: cardによる異常耐性発動\n",sd->bl.id); return 0; diff --git a/src/map/tmw.c b/src/map/tmw.c index 2331a23..25aa55b 100644 --- a/src/map/tmw.c +++ b/src/map/tmw.c @@ -43,41 +43,45 @@ int tmw_CheckChatSpam(struct map_session_data *sd, char* message) { sd->chat_lines_in = 0; } - sd->chat_lines_in++; - - if (message) { - // Penalty for repeating - if (strncmp(sd->chat_lastmsg, message, battle_config.chat_maxline) == 0) - sd->chat_lines_in += battle_config.chat_lame_penalty; + if (now > sd->chat_repeat_reset_due) { + sd->chat_repeat_reset_due = now + (battle_config.chat_spam_threshold * 60); + sd->chat_total_repeats = 0; + } - // Penalty for lame, it can stack on top of the repeat penalty. - if (tmw_CheckChatLameness(sd, message)) - sd->chat_lines_in += battle_config.chat_lame_penalty; + sd->chat_lines_in++; - strncpy((char*)sd->chat_lastmsg, message, battle_config.chat_maxline); + // Penalty for repeats. + if (strncmp(sd->chat_lastmsg, message, tmw_ShorterStrlen(sd->chat_lastmsg, message)) == 0) { + sd->chat_lines_in += battle_config.chat_lame_penalty; + sd->chat_total_repeats++; } else { - // No message means we're checking another type of spam. - // Most other types are pretty lame.. - sd->chat_lines_in += battle_config.chat_lame_penalty; + sd->chat_total_repeats=0; } - if (sd->chat_lines_in >= battle_config.chat_spam_flood) { - sd->chat_lines_in = 0; + // Penalty for lame, it can stack on top of the repeat penalty. + if (tmw_CheckChatLameness(sd, message)) + sd->chat_lines_in += battle_config.chat_lame_penalty; + + strncpy((char*)sd->chat_lastmsg, message, battle_config.chat_maxline); + + if (sd->chat_lines_in >= battle_config.chat_spam_flood || sd->chat_total_repeats >= battle_config.chat_spam_flood) { + sd->chat_lines_in = sd->chat_total_repeats = 0; if (battle_config.chat_spam_ban > 0) { - tmw_GmHackMsg("Spam detected from character '%s' (account: %d)", sd->status.name, sd->status.account_id); - clif_displaymessage(sd->fd, "You have been banned for spamming. Please do not spam."); - tmw_GmHackMsg("This player has been banned for %d hour(s).", battle_config.chat_spam_ban); + tmw_GmHackMsg("%s has been autobanned for chat spam", sd->status.name); + gm_log("server(0,0) Server : @autoban %s %dh (chat spam)", sd->status.name, battle_config.chat_spam_ban); + clif_displaymessage(sd->fd, "You have been banned for spamming. Please do not spam."); chrif_char_ask_name(-1, sd->status.name, 2, 0, 0, 0, battle_config.chat_spam_ban, 0, 0); // type: 2 - ban (year, month, day, hour, minute, second) clif_setwaitclose(sd->fd); } - + return 1; } - if (battle_config.chat_spam_ban && sd->chat_lines_in >= battle_config.chat_spam_warn) { + if (battle_config.chat_spam_ban && + (sd->chat_lines_in >= battle_config.chat_spam_warn || sd->chat_total_repeats >= battle_config.chat_spam_warn)) { clif_displaymessage(sd->fd, "WARNING : You are about to be automaticly banned for spam!"); clif_displaymessage(sd->fd, "WARNING : Please slow down, do not repeat, and do not SHOUT!"); } @@ -85,6 +89,13 @@ int tmw_CheckChatSpam(struct map_session_data *sd, char* message) { return 0; } +// Compares the length of two strings and returns that of the shorter +int tmw_ShorterStrlen(char *s1, char *s2) { + int s1_len = strlen(s1); + int s2_len = strlen(s2); + return(s2_len >= s1_len ? s1_len : s2_len); +} + // Returns true if more than 50% of input message is caps or punctuation int tmw_CheckChatLameness(struct map_session_data *sd, char *message) { @@ -136,14 +147,14 @@ int tmw_CheckTradeSpam(struct map_session_data *sd) { sd->trades_in = 0; if (battle_config.trade_spam_ban > 0) { - tmw_GmHackMsg("Trade spam detected from character '%s' (account: %d)", sd->status.name, sd->status.account_id); - clif_displaymessage(sd->fd, "You have been banned for trade spamming. Please do not trade spam."); - tmw_GmHackMsg("This player has been banned for %d hour(s).", battle_config.trade_spam_ban); + tmw_GmHackMsg("%s has been autobanned for trade spam", sd->status.name); + gm_log("server(0,0) Server : @autoban %s %dh (trade spam)", sd->status.name, battle_config.trade_spam_ban); + clif_displaymessage(sd->fd, "You have been banned for trade spamming. Please do not trade spam."); chrif_char_ask_name(-1, sd->status.name, 2, 0, 0, 0, battle_config.trade_spam_ban, 0, 0); // type: 2 - ban (year, month, day, hour, minute, second) clif_setwaitclose(sd->fd); } - + return 1; } @@ -171,14 +182,14 @@ int tmw_CheckSitSpam(struct map_session_data *sd) { sd->sits_in = 0; if (battle_config.sit_spam_ban > 0) { - tmw_GmHackMsg("Sit spam detected from character '%s' (account: %d)", sd->status.name, sd->status.account_id); - clif_displaymessage(sd->fd, "You have been banned for sit spamming. Please do not sit spam."); - tmw_GmHackMsg("This player has been banned for %d hour(s).", battle_config.sit_spam_ban); + tmw_GmHackMsg("%s has been autobanned for sit spam", sd->status.name); + gm_log("server(0,0) Server : @autoban %s %dh (sit spam)", sd->status.name, battle_config.sit_spam_ban); + clif_displaymessage(sd->fd, "You have been banned for sit spamming. Please do not sit spam."); chrif_char_ask_name(-1, sd->status.name, 2, 0, 0, 0, battle_config.sit_spam_ban, 0, 0); // type: 2 - ban (year, month, day, hour, minute, second) clif_setwaitclose(sd->fd); } - + return 1; } diff --git a/src/map/tmw.h b/src/map/tmw.h index 8580810..8248a71 100644 --- a/src/map/tmw.h +++ b/src/map/tmw.h @@ -3,6 +3,7 @@ #include "map.h" int tmw_CheckChatSpam(struct map_session_data *sd, char* message); +int tmw_ShorterStrlen(char *s1, char *s2); int tmw_CheckChatLameness(struct map_session_data *sd, char *message); void tmw_GmHackMsg(const char *fmt, ...); int tmw_CheckTradeSpam(struct map_session_data *sd); |