summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJared Adams <jaxad0127@gmail.com>2009-08-31 13:22:39 -0600
committerJared Adams <jaxad0127@gmail.com>2009-08-31 13:22:39 -0600
commit67a8847e17aa72981bbf3b4c15167cc0ef499da1 (patch)
tree30b07708a5893712ea1a0bb4835881caa3dd97f7 /src
parent0e36f6e8d82e7cb0f01683454790a7123ea03197 (diff)
parentdbd9d0321c66deeecf01445f8298aa5076391fbd (diff)
downloadtmwa-67a8847e17aa72981bbf3b4c15167cc0ef499da1.tar.gz
tmwa-67a8847e17aa72981bbf3b4c15167cc0ef499da1.tar.bz2
tmwa-67a8847e17aa72981bbf3b4c15167cc0ef499da1.tar.xz
tmwa-67a8847e17aa72981bbf3b4c15167cc0ef499da1.zip
Merge commit 'taw/master'
Diffstat (limited to 'src')
-rw-r--r--src/char/Makefile4
-rw-r--r--src/char/char.c13
-rw-r--r--src/char/int_storage.c9
-rw-r--r--src/common/Makefile3
-rw-r--r--src/common/core.c10
-rw-r--r--src/common/lock.c11
-rw-r--r--src/common/mt_rand.c110
-rw-r--r--src/common/mt_rand.h8
-rw-r--r--src/common/utils.h6
-rw-r--r--src/ladmin/GNUmakefile4
-rw-r--r--src/ladmin/Makefile4
-rw-r--r--src/login/Makefile4
-rw-r--r--src/login/login.c7
-rw-r--r--src/map/Makefile2
-rw-r--r--src/map/atcommand.c99
-rw-r--r--src/map/atcommand.h2
-rw-r--r--src/map/battle.c1
-rw-r--r--src/map/clif.c10
-rw-r--r--src/map/map.c6
-rw-r--r--src/map/map.h2
-rw-r--r--src/map/pc.c27
-rw-r--r--src/map/skill.c136
-rw-r--r--src/map/tmw.c67
-rw-r--r--src/map/tmw.h1
24 files changed, 379 insertions, 167 deletions
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);