Преглед изворни кода

Merge branch 'rathena/master'

Cydh Ramdh пре 11 година
родитељ
комит
84b5dbfb7e

+ 7 - 3
db/pre-re/skill_require_db.txt

@@ -23,9 +23,13 @@
 //  peco = Requires riding a peco
 //
 // 'RequiredStatuses'
-//  Fill the value only with SC_STATUS (see db/const.txt for more details)
-//  Usage for multiple status requirements: SC_STATUS1:SC_STATUS2:SC_STATUS3 (max. is MAX_SKILL_STATUS_REQUIRE)
-//  Use any number or SC_ALL will disable status requirements
+//	Fill the value only with SC_STATUS (see db/const.txt for more details)
+//	Usage for multiple status requirements: SC_STATUS1:SC_STATUS2:SC_STATUS3
+//	Max. multiple value is 3 (skill.h: MAX_SKILL_STATUS_REQUIRE)
+//	Use any number or SC_ALL will disable status requirements
+// 'RequiredEquipment'
+//	Specified equipment to be equipped. For multiple values, use : as delimiter.
+//	Max. multiple value is 10 (skill.h: MAX_SKILL_EQUIP_REQUIRE)
 
 //****
 // SM Swordman

+ 3 - 0
db/re/item_db.txt

@@ -6527,6 +6527,9 @@
 13181,Novice_Shotgun,Novice Shotgun,4,0,,1000,80,,9,0,0x41000000,1,2,34,4,1,0,20,{},{},{}
 13182,Novice_Gatling,Novice Gatling,4,0,,1500,40,,9,0,0x41000000,1,2,34,4,1,0,19,{},{},{}
 13183,Novice_Grenade_Launcher,Novice Grenade Launcher,4,0,,1500,40,,9,0,0x41000000,1,2,34,4,1,0,21,{},{},{}
+13194,Peace_Breaker,Peace Breaker,4,1,,1400,250,,,,0x41000000,63,2,2,3,120,,20,{ bonus bHit,-25; bonus bAspdRate,25; },{},{}
+13196,Peace_Breaker,Peace Breaker,4,1,,1400,250,,,,0x41000000,63,2,2,3,120,,20,{ bonus bHit,-25; bonus bAspdRate,25; },{},{}
+13197,Mini_Mei,Mini Mei,4,1,,2500,220,,,,0x41000000,63,2,2,2,106,,19,{},{},{}
 // Bullets
 13200,Bullet,Bullet,10,1,,2,10,,,,0x41000000,63,2,32768,,1,,3,{},{},{}
 13201,Silver_Bullet,Silver Bullet,10,15,,2,15,,,,0x41000000,63,2,32768,,1,,3,{ bonus bAtkEle,Ele_Holy; },{},{}

+ 2 - 2
db/re/job_db1.txt

@@ -52,7 +52,7 @@
 // Super Novice
 23,	20000,0    ,500  ,100  ,440  ,590  ,610  ,2000 ,2000 ,2000 ,540  ,2000 ,540  ,540  ,690  ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,690  ,540
 // Gunslinger
-24,	28000,75   ,0    ,400  ,540  ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,490  ,590  ,440  ,940  ,1040 ,2000 ,2000 ,600
+24,	28000,75   ,0    ,400  ,540  ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,490  ,590  ,540  ,940  ,1040 ,2000 ,2000 ,600
 // Ninja
 25,	26000,80   ,0    ,300  ,440  ,470  ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,590  ,2000 ,500
 // Novice High
@@ -270,4 +270,4 @@
 // Oboro
 4212,	26000,80   ,  0  ,300  ,400  ,500  ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 , 750 ,2000 ,500
 // Rebellion
-4215,   28000,75   ,  0  ,400  ,540  ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,490  ,590  ,440  ,940  ,1040 ,2000 ,2000 ,600
+4215,   28000,75   ,  0  ,400  ,540  ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,2000 ,520  ,620  ,570  ,970  ,1070 ,2000 ,2000 ,600

+ 7 - 3
db/re/skill_require_db.txt

@@ -23,9 +23,13 @@
 //  peco = Requires riding a peco
 //
 // 'RequiredStatuses'
-//  Fill the value only with SC_STATUS (see db/const.txt for more details)
-//  Usage for multiple status requirements: SC_STATUS1:SC_STATUS2:SC_STATUS3 (max. is MAX_SKILL_STATUS_REQUIRE)
-//  Use any number or SC_ALL will disable status requirements
+//	Fill the value only with SC_STATUS (see db/const.txt for more details)
+//	Usage for multiple status requirements: SC_STATUS1:SC_STATUS2:SC_STATUS3
+//	Max. multiple value is 3 (skill.h: MAX_SKILL_STATUS_REQUIRE)
+//	Use any number or SC_ALL will disable status requirements
+// 'RequiredEquipment'
+//	Specified equipment to be equipped. For multiple values, use : as delimiter.
+//	Max. multiple value is 10 (skill.h: MAX_SKILL_EQUIP_REQUIRE)
 
 //****
 // SM Swordman

+ 24 - 23
db/skill_copyable_db.txt

@@ -10,31 +10,32 @@
 //    SkillName,Option{,JobAllowed{,RequirementRemoved}}
 // ====================================================
 // Option is using bitmask of skill that can be copied by:
-//    1 = Plagiarism
-//    2 = Reproduce
+//	1 = Plagiarism
+//	2 = Reproduce
 // JobAllowed, the skill only can be copied by:
-//    (0 or the default value makes all jobs can copy the skill)
-//    1    = Rogue
-//    2    = Stalker
-//    4    = Shadow Chaser
-//    8    = Trans. Shadow Chaser
-//    16   = Baby Rouge
-//    32   = Baby Shadow Chaser
+//	(0 or the default value makes all jobs can copy the skill)
+//	1	= Rogue
+//	2	= Stalker
+//	4	= Shadow Chaser
+//	8	= Trans. Shadow Chaser
+//	16	= Baby Rouge
+//	32	= Baby Shadow Chaser
 // RequirementRemoved, decide which requirement(s) that will be removed while checking.
-//    0    = makes the requirement(s) same like original requirement(s)
-//    1    = hp
-//    2    = maxhptrigger
-//    4    = sp
-//    8    = hprate
-//    16   = sprate
-//    32   = zeny
-//    64   = weapon type
-//    128  = ammo (with the amount)
-//    256  = state
-//    512  = statuses
-//    1024 = spirit sphere
-//    2048 = items (with the amount)
-//    (see 'skill_require_db.txt' for requirement(s) detail)
+//	   0 = makes the requirement(s) same like original requirement(s)
+//	   1 = hp
+//	   2 = maxhptrigger
+//	   4 = sp
+//	   8 = hprate
+//	  16 = sprate
+//	  32 = zeny
+//	  64 = weapon type
+//	 128 = ammo (with the amount)
+//	 256 = state
+//	 512 = statuses
+//	1024 = spirit sphere
+//	2048 = items (with the amount)
+//  4096 = equipments
+// (see 'skill_require_db.txt' for requirement(s) detail)
 // ====================================================
 // Example of advanced usage:
 //AS_SONICBLOW,2,63,64

+ 3 - 0
sql-files/item_db_re.sql

@@ -6558,6 +6558,9 @@ REPLACE INTO `item_db_re` VALUES (13180,'Novice_Rifle','Novice Rifle',4,0,NULL,5
 REPLACE INTO `item_db_re` VALUES (13181,'Novice_Shotgun','Novice Shotgun',4,0,NULL,1000,'80',NULL,9,0,0x41000000,1,2,34,4,'1',0,20,NULL,NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (13182,'Novice_Gatling','Novice Gatling',4,0,NULL,1500,'40',NULL,9,0,0x41000000,1,2,34,4,'1',0,19,NULL,NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (13183,'Novice_Grenade_Launcher','Novice Grenade Launcher',4,0,NULL,1500,'40',NULL,9,0,0x41000000,1,2,34,4,'1',0,21,NULL,NULL,NULL);
+REPLACE INTO `item_db_re` VALUES (13194,'Peace_Breaker','Peace Breaker,',4,1,NULL,1400,'250',NULL,NULL,NULL,0x41000000,63,2,2,3,'120',0,20,'bonus bHit,-25; bonus bAspdRate,25;',NULL,NULL);
+REPLACE INTO `item_db_re` VALUES (13196,'Peace_Breaker','Peace Breaker,',4,1,NULL,1400,'250',NULL,NULL,NULL,0x41000000,63,2,2,3,'120',0,20,'bonus bHit,-25; bonus bAspdRate,25;',NULL,NULL);
+REPLACE INTO `item_db_re` VALUES (13197,'Mini_Mei','Mini Mei,',4,1,NULL,2500,'220',NULL,NULL,NULL,0x41000000,63,2,2,2,'106',0,19,NULL,NULL,NULL);
 # Bullets
 REPLACE INTO `item_db_re` VALUES (13200,'Bullet','Bullet',10,1,NULL,2,'10',NULL,NULL,NULL,0x41000000,63,2,32768,NULL,'1',NULL,3,NULL,NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (13201,'Silver_Bullet','Silver Bullet',10,15,NULL,2,'15',NULL,NULL,NULL,0x41000000,63,2,32768,NULL,'1',NULL,3,'bonus bAtkEle,Ele_Holy;',NULL,NULL);

+ 100 - 52
src/char/char.c

@@ -149,6 +149,7 @@ struct char_session_data {
 	unsigned int char_moves[MAX_CHARS]; // character moves left
 	uint8 isvip;
 	time_t unban_time[MAX_CHARS];
+	int charblock_timer;
 };
 
 struct startitem {
@@ -1087,6 +1088,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
 
 	for( i = 0; i < MAX_CHARS; i++ ){
 		sd->found_char[i] = -1;
+		sd->unban_time[i] = 0;
 	}
 
 	// read char data
@@ -1950,42 +1952,85 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p)
 	return 106+offset;
 }
 
+
+
 //----------------------------------------
 // Tell client how many pages, kRO sends 17 (Yommy)
 //----------------------------------------
 void char_charlist_notify( int fd, struct char_session_data* sd ){
+	int found=0, count=0, i=0;
+	for(i=0; i<MAX_CHARS; i++){
+		if(sd->found_char[i] != -1){
+			found=1;
+		}
+		if(i%3 && found){ //each page contains 3char max
+			count++;
+			found=0;
+		}
+	}
+	
 	WFIFOHEAD(fd, 6);
 	WFIFOW(fd, 0) = 0x9a0;
 	// pages to req / send them all in 1 until mmo_chars_fromsql can split them up
-	WFIFOL(fd, 2) = (sd->char_slots>3)?sd->char_slots/3:1; //int TotalCnt (nb page to load)
+	WFIFOL(fd, 2) = count?count:1;
 	WFIFOSET(fd,6);
 }
 
+void char_block_character( int fd, struct char_session_data* sd );
+int charblock_timer(int tid, unsigned int tick, int id, intptr_t data)
+{
+	struct char_session_data* sd=NULL;
+	int i=0;
+	ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == id);
+
+	if(sd == NULL || sd->charblock_timer==INVALID_TIMER) //has disconected or was required to stop
+		return 0;
+	if (sd->charblock_timer != tid){
+		sd->charblock_timer = INVALID_TIMER;
+		return 0;
+	}
+	char_block_character(i,sd);
+	return 0;
+}
 /*
  * 0x20d <PacketLength>.W <TAG_CHARACTER_BLOCK_INFO>24B (HC_BLOCK_CHARACTER)
  * <GID>L <szExpireDate>20B (TAG_CHARACTER_BLOCK_INFO)
  */
-void char_block_character( int fd, struct char_session_data* sd ){
-	int i=0, len=4;
-	char szExpireDate[20];
+void char_block_character( int fd, struct char_session_data* sd){
+	int i=0, j=0, len=4;
 	time_t now = time(NULL);
+	
+	WFIFOHEAD(fd, 4+MAX_CHARS*24);
+	WFIFOW(fd, 0) = 0x20d;
 
-	ARR_FIND(0, MAX_CHARS, i, sd->unban_time[i] > now); //should we use MAX_CHARS or sd->charslot
-	if(i < MAX_CHARS){
-		memset(szExpireDate,'\0',20);
-		WFIFOHEAD(fd, 4+MAX_CHARS*24);
-		WFIFOW(fd, 0) = 0x20d;
-
-		for(i=0; i<MAX_CHARS; i++){
+	for(i=0; i<MAX_CHARS; i++){
+		if(sd->found_char[i] == -1) 
+			continue;
+		if(sd->unban_time[i]){
 			if( sd->unban_time[i] > now ) {
-				WFIFOL(fd, 4+i*24) = sd->found_char[i]; //gid
+				char szExpireDate[21];
+				WFIFOL(fd, 4+j*24) = sd->found_char[i];
 				timestamp2string(szExpireDate, 20, sd->unban_time[i], "%Y-%m-%d %H:%M:%S");
-				memcpy(WFIFOP(fd,8+i*24),szExpireDate,20);
-				len+=24;
+				memcpy(WFIFOP(fd,8+j*24),szExpireDate,20);
+			}
+			else {
+				WFIFOL(fd, 4+j*24) = 0;
+				sd->unban_time[i] = 0;
+				if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `unban_time`='0' WHERE `char_id`='%d' LIMIT 1", char_db, sd->found_char[i]) )
+					Sql_ShowDebug(sql_handle);
 			}
+			len+=24;
+			j++; //pkt list idx
 		}
-		WFIFOW(fd, 2) = len; //packet len
-		WFIFOSET(fd,len);
+	}
+	WFIFOW(fd, 2) = len; //packet len
+	WFIFOSET(fd,len);
+		
+	ARR_FIND(0, MAX_CHARS, i, sd->unban_time[i] > now); //sd->charslot only have productible char
+	if(i < MAX_CHARS ){
+		sd->charblock_timer = add_timer(
+			gettick() + 10000,	// each 10s resend that list
+			charblock_timer, sd->account_id, 0);
 	}
 }
 
@@ -2010,7 +2055,7 @@ int mmo_char_send006b(int fd, struct char_session_data* sd){
 	if(newvers) //20100413
 		offset += 3;
 	if (save_log)
-		ShowInfo("Loading Char Data ("CL_BOLD"%d"CL_RESET")\n",sd->account_id);
+		ShowInfo("Loading Char Data 6b ("CL_BOLD"%d"CL_RESET")\n",sd->account_id);
 
 	j = 24 + offset; // offset
 	WFIFOHEAD(fd,j + MAX_CHARS*MAX_CHAR_BUF);
@@ -2038,7 +2083,7 @@ int mmo_char_send006b(int fd, struct char_session_data* sd){
 //----------------------------------------
 void mmo_char_send082d(int fd, struct char_session_data* sd) {
 	if (save_log)
-		ShowInfo("Loading Char Data ("CL_BOLD"%d"CL_RESET")\n",sd->account_id);
+		ShowInfo("Loading Char Data 82d ("CL_BOLD"%d"CL_RESET")\n",sd->account_id);
 	WFIFOHEAD(fd,29);
 	WFIFOW(fd,0) = 0x82d;
 	WFIFOW(fd,2) = 29;
@@ -2056,11 +2101,12 @@ void mmo_char_send(int fd, struct char_session_data* sd){
 	if(sd->version > date2version(20130000) ){
 		mmo_char_send082d(fd,sd);
 		char_charlist_notify(fd,sd);
-		char_block_character(fd,sd);
 	}
 	//else
 	//@FIXME dump from kro doesn't show 6b transmission
 	mmo_char_send006b(fd,sd);
+	if(sd->version > date2version(20060819) )
+		char_block_character(fd,sd);
 }
 
 int char_married(int pl1, int pl2)
@@ -2950,14 +2996,15 @@ void mapif_on_disconnect(int id)
 }
 
 int mapif_parse_reqcharban(int fd){
-	if (RFIFOREST(fd) < 10)
+	if (RFIFOREST(fd) < 10+NAME_LENGTH)
 		return 0;
-	else {	
-		int cid = RFIFOL(fd,2);
+	else {
+		//int aid = RFIFOL(fd,2); aid of player who as requested the ban
 		int timediff = RFIFOL(fd,6);
-		RFIFOSKIP(fd,10);
+		const char* name = (char*)RFIFOP(fd,10); // name of the target character
+		RFIFOSKIP(fd,10+NAME_LENGTH);
 
-		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id` `unban_time` FROM `%s` WHERE `char_id` = '%d'", char_db, cid) )
+		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`char_id`,`unban_time` FROM `%s` WHERE `name` = '%s'", char_db, name) )
 			Sql_ShowDebug(sql_handle);
 		else if( Sql_NumRows(sql_handle) == 0 ){
 			return -1; // 1-player not found
@@ -2967,45 +3014,46 @@ int mapif_parse_reqcharban(int fd){
 			Sql_FreeResult(sql_handle);
 			return -1;
 		} else {
-			int aid;
+			int t_cid=0,t_aid=0;
 			char* data;
 			time_t unban_time;
+			time_t now = time(NULL);
+			SqlStmt* stmt = SqlStmt_Malloc(sql_handle);
 
-			Sql_GetData(sql_handle, 0, &data, NULL); aid = atoi(data);
-			Sql_GetData(sql_handle, 1, &data, NULL); unban_time = atol(data);
+			Sql_GetData(sql_handle, 0, &data, NULL); t_aid = atoi(data);
+			Sql_GetData(sql_handle, 1, &data, NULL); t_cid = atoi(data);
+			Sql_GetData(sql_handle, 2, &data, NULL); unban_time = atol(data);
 			Sql_FreeResult(sql_handle);
 
-
 			if(timediff<0 && unban_time==0) return 0; //attemp to reduce time of a non banned account ?!?
-			else if(unban_time==0) unban_time=time(NULL); //new entry
-			unban_time += timediff;
+			else if(unban_time<now) unban_time=now; //new entry
+			unban_time += timediff; //alterate the time
+			if( unban_time < now ) unban_time=0; //we have totally reduce the time
+			
+			if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
+					  "UPDATE `%s` SET `unban_time` = ? WHERE `char_id` = ? LIMIT 1",
+					  char_db)
+				|| SQL_SUCCESS != SqlStmt_BindParam(stmt,  0, SQLDT_LONG,   (void*)&unban_time,   sizeof(unban_time))
+				|| SQL_SUCCESS != SqlStmt_BindParam(stmt,  1, SQLDT_INT,    (void*)&t_cid,     sizeof(t_cid))
+				|| SQL_SUCCESS != SqlStmt_Execute(stmt)
+
+				) {
+				SqlStmt_ShowDebug(stmt);
+				SqlStmt_Free(stmt);
+				return -1;
+			}
+			SqlStmt_Free(stmt);
+			
 			// condition applies; send to all map-servers to disconnect the player
-			if( unban_time > time(NULL) ) {
-				unsigned char buf[11];
-				SqlStmt* stmt = SqlStmt_Malloc(sql_handle);
-				if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
-						  "UPDATE `%s` SET `unban_time` = ? WHERE `char_id` = ? LIMIT 1",
-						  char_db)
-					|| SQL_SUCCESS != SqlStmt_BindParam(stmt,  0, SQLDT_LONG,   (void*)&unban_time,   sizeof(unban_time))
-					|| SQL_SUCCESS != SqlStmt_BindParam(stmt,  1, SQLDT_INT,    (void*)&cid,     sizeof(cid))
-					|| SQL_SUCCESS != SqlStmt_Execute(stmt)
-
-					) {
-					SqlStmt_ShowDebug(stmt);
-					SqlStmt_Free(stmt);
-					return -1;
-				}
-				else {
+			if( unban_time > now ) { 
+					unsigned char buf[11];
 					WBUFW(buf,0) = 0x2b14;
-					WBUFL(buf,2) = aid;
+					WBUFL(buf,2) = t_cid;
 					WBUFB(buf,6) = 2;
 					WBUFL(buf,7) = (unsigned int)unban_time;
 					mapif_sendall(buf, 11);
-
 					// disconnect player if online on char-server
-					disconnect_player(aid);
-				}
-				SqlStmt_Free(stmt);
+					disconnect_player(t_aid);
 			}
 		}
 	}
@@ -3015,7 +3063,7 @@ int mapif_parse_reqcharban(int fd){
 int mapif_parse_reqcharunban(int fd){
 	if (RFIFOREST(fd) < 6)
 		return 0;
-	else {	
+	else {
 		int cid = RFIFOL(fd,2);
 		RFIFOSKIP(fd,6);
 		

+ 2 - 2
src/map/atcommand.c

@@ -2826,8 +2826,8 @@ ACMD_FUNC(char_ban)
 	
 	if(bantype==2) 
 		chrif_req_login_operation(sd->status.account_id, atcmd_player_name, 2, timediff, 0, 0); // type: 2 - ban
-	else
-		chrif_req_charban(sd->status.char_id,timediff);
+	else 
+		chrif_req_charban(sd->status.account_id, atcmd_player_name,timediff);
 	
 	safesnprintf(output,sizeof(output),msg_txt(sd,88),bantype==6?"char":"login"); // Sending request to %s server...
 	clif_displaymessage(fd, output);

+ 2 - 2
src/map/battle.c

@@ -5923,10 +5923,10 @@ int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, i
 					}
 				}
 
-                if( sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 2 && !(src->type == BL_MOB && is_boss(src)) ){
+				if( sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 2 && !(src->type == BL_MOB && is_boss(src)) ){
 						rdamage += damage * sc->data[SC_SHIELDSPELL_DEF]->val2 / 100;
 						if (rdamage < 1) rdamage = 1;
-                }
+				}
 			}
 		}
 	} else {

+ 17 - 15
src/map/chrif.c

@@ -46,7 +46,7 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
 	11,10,10, 0,11, -1,266,10,	// 2b10-2b17: U->2b10, U->2b11, U->2b12, F->2b13, U->2b14, U->2b15, U->2b16, U->2b17
 	 2,10, 2,-1,-1,-1, 2, 7,	// 2b18-2b1f: U->2b18, U->2b19, U->2b1a, U->2b1b, U->2b1c, U->2b1d, U->2b1e, U->2b1f
 	-1,10, 8, 2, 2,14,19,19,	// 2b20-2b27: U->2b20, U->2b21, U->2b22, U->2b23, U->2b24, U->2b25, U->2b26, U->2b27
-	10,10, 6,15, 0, 6,-1,-1,	// 2b28-2b2f: U->2b28, U->2b29, U->2b2a, U->2b2b, F->2b2c, U->2b2d, U->2b2e, U->2b2f
+	-1,10, 6,15, 0, 6,-1,-1,	// 2b28-2b2f: U->2b28, U->2b29, U->2b2a, U->2b2b, F->2b2c, U->2b2d, U->2b2e, U->2b2f
  };
 
 //Used Packets:
@@ -816,8 +816,8 @@ int chrif_changeemail(int id, const char *actual_email, const char *new_email) {
 /**
  * S 2b0e <accid>.l <name>.24B <operation_type>.w <timediff>L <val1>L <val2>L
  * Send an account modification request to the login server (via char server).
- * @aid : Player account id
- * @character_name : Player name
+ * @aid : Player requesting operation account id
+ * @character_name : Target of operation Player name
  * @operation_type : 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex (use next function for 5), 6 vip, 7 bank 
  * @timediff : tick to add or remove to unixtimestamp
  * @val1 : extra data value to transfer for operation
@@ -1029,20 +1029,21 @@ int chrif_deadopt(int father_id, int mother_id, int child_id) {
 /*==========================================
  * Disconnection of a player (account has been banned of has a status, from login/char-server) by [Yor]
  *------------------------------------------*/
-int chrif_accountban(int fd) {
-	int acc, res=0;
+int chrif_ban(int fd) {
+	int id, res=0;
 	struct map_session_data *sd;
 
-	acc = RFIFOL(fd,2);
+	id = RFIFOL(fd,2);
 	res = RFIFOB(fd,6); // 0: change of statut, 1: ban, 2 charban
 
 	if ( battle_config.etc_log )
-		ShowNotice("chrif_accountban %d.\n", acc);
+		ShowNotice("chrif_ban %d.type = %s \n", id, res==1?"account":"char");
 
-	sd = map_id2sd(acc);
+	if(res==2)  sd = map_charid2sd(id);
+	else sd = map_id2sd(id);
 
-	if ( acc < 0 || sd == NULL ) {
-		ShowError("chrif_accountban failed - player not online.\n");
+	if ( id < 0 || sd == NULL ) {
+		//nothing to do on map if player not connected
 		return 0;
 	}
 
@@ -1070,14 +1071,15 @@ int chrif_accountban(int fd) {
 	return 0;
 }
 
-int chrif_req_charban(int cid, int timediff){
+int chrif_req_charban(int aid, const char* character_name, int timediff){
 	chrif_check(-1);
 	
-	WFIFOHEAD(char_fd,10);
+	WFIFOHEAD(char_fd,10+NAME_LENGTH);
 	WFIFOW(char_fd,0) = 0x2b28;
-	WFIFOL(char_fd,2) = cid;
+	WFIFOL(char_fd,2) = aid;
 	WFIFOL(char_fd,6) = timediff;
-	WFIFOSET(char_fd,10);
+	safestrncpy((char*)WFIFOP(char_fd,10), character_name, NAME_LENGTH);
+	WFIFOSET(char_fd,10+NAME_LENGTH); //default 34
 	return 0;
 }
 
@@ -1610,7 +1612,7 @@ int chrif_parse(int fd) {
 			case 0x2b0d: chrif_changedsex(fd); break;
 			case 0x2b0f: chrif_ack_login_req(RFIFOL(fd,2), (char*)RFIFOP(fd,6), RFIFOW(fd,30), RFIFOW(fd,32)); break;
 			case 0x2b12: chrif_divorceack(RFIFOL(fd,2), RFIFOL(fd,6)); break;
-			case 0x2b14: chrif_accountban(fd); break;
+			case 0x2b14: chrif_ban(fd); break;
 			case 0x2b1b: chrif_recvfamelist(fd); break;
 			case 0x2b1d: chrif_load_scdata(fd); break;
 			case 0x2b1e: chrif_update_ip(fd); break;

+ 1 - 1
src/map/chrif.h

@@ -67,7 +67,7 @@ int chrif_send_report(char* buf, int len);
 
 void chrif_parse_ack_vipActive(int fd);
 
-int chrif_req_charban(int aid, int timediff);
+int chrif_req_charban(int aid, const char* character_name, int timediff);
 int chrif_req_charunban(int cid);
 
 int chrif_load_bankdata(int fd);

+ 2 - 1
src/map/pc.c

@@ -8499,7 +8499,7 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data) {
 	int index, idx, success = 0;
 
 	for( i = 0; i < data->combos_count; i++ ) {
-		int *combo_idx = aMalloc(data->combos[i]->count);
+		int16 *combo_idx = NULL;
 		/* ensure this isn't a duplicate combo */
 		if( sd->combos.bonus != NULL ) {
 			int x;
@@ -8510,6 +8510,7 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data) {
 				continue;
 		}
 
+		CREATE(combo_idx,int16,data->combos[i]->count);
 		for( j = 0; j < data->combos[i]->count; j++ ) {
 			int id = data->combos[i]->nameid[j];
 			bool found = false;

+ 0 - 2
src/map/script.c

@@ -18709,9 +18709,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(getserverdef,"i"),
 	BUILDIN_DEF2(montransform, "transform", "vii????"), // Monster Transform [malufett/Hercules]
 	BUILDIN_DEF(vip_status,"i?"),
-#ifdef VIP_ENABLE
 	BUILDIN_DEF(vip_time,"i?"),
-#endif
 	BUILDIN_DEF(bonus_script,"si???"),
 	BUILDIN_DEF(addspiritball,"ii?"),
 	BUILDIN_DEF(delspiritball,"i?"),

+ 19 - 17
src/map/skill.c

@@ -14035,7 +14035,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
 	}
 
 	//check if equiped item
-	for (i = 0; i < 10; i++) {
+	for (i = 0; i < MAX_SKILL_EQUIP_REQUIRE; i++) {
 		int reqeqit = require.eqItem[i];
 		if(!reqeqit) break; //no more required item get out of here
 		if (!pc_checkequip2(sd,reqeqit)) {
@@ -14606,18 +14606,19 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
 	//Check if player is using the copied skill [Cydh]
 	if (sd->status.skill[idx].flag == SKILL_FLAG_PLAGIARIZED) {
 		uint16 req_opt = skill_db[idx].copyable.req_opt;
-		if (req_opt&0x001) req.hp = 0;
-		if (req_opt&0x002) req.mhp = 0;
-		if (req_opt&0x004) req.sp = 0;
-		if (req_opt&0x008) req.hp_rate = 0;
-		if (req_opt&0x010) req.sp_rate = 0;
-		if (req_opt&0x020) req.zeny = 0;
-		if (req_opt&0x040) req.weapon = 0;
-		if (req_opt&0x080) { req.ammo = 0; req.ammo_qty = 0; }
-		if (req_opt&0x100) req.state = ST_NONE;
-		if (req_opt&0x200) { memset(req.status,SC_NONE,sizeof(req.status)); }
-		if (req_opt&0x400) req.spiritball = 0;
-		if (req_opt&0x800) { memset(req.itemid,0,sizeof(req.itemid)); memset(req.amount,0,sizeof(req.amount)); }
+		if (req_opt&0x0001) req.hp = 0;
+		if (req_opt&0x0002) req.mhp = 0;
+		if (req_opt&0x0004) req.sp = 0;
+		if (req_opt&0x0008) req.hp_rate = 0;
+		if (req_opt&0x0010) req.sp_rate = 0;
+		if (req_opt&0x0020) req.zeny = 0;
+		if (req_opt&0x0040) req.weapon = 0;
+		if (req_opt&0x0080) { req.ammo = 0; req.ammo_qty = 0; }
+		if (req_opt&0x0100) req.state = ST_NONE;
+		if (req_opt&0x0200) memset(req.status,SC_NONE,sizeof(req.status));
+		if (req_opt&0x0400) req.spiritball = 0;
+		if (req_opt&0x0800) { memset(req.itemid,0,sizeof(req.itemid)); memset(req.amount,0,sizeof(req.amount)); }
+		if (req_opt&0x1000) memset(req.eqItem,0,sizeof(req.eqItem));
 	}
 
 	return req;
@@ -18576,7 +18577,7 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
 	p = strtok(split[11],":");
 	for( i = 0; i < MAX_SKILL_STATUS_REQUIRE && p != NULL; i++ ) {
 		int status = SC_NONE;
-		script_get_constant(trim(p), &status);
+		script_get_constant(trim(p),&status);
 		if (status > SC_NONE) {
 			skill_db[idx].require.status[skill_db[idx].require.status_count] = (enum sc_type)status;
 			skill_db[idx].require.status_count++;
@@ -18594,9 +18595,9 @@ static bool skill_parse_row_requiredb(char* split[], int columns, int current)
 	//require equiped
 	memset(skill_db[idx].require.eqItem,0,sizeof(skill_db[idx].require.eqItem));
 	p = strtok(split[33],":");
-	for( i = 0; i < 10 && p != NULL; i++ ) {
+	for( i = 0; i < MAX_SKILL_EQUIP_REQUIRE && p != NULL; i++ ) {
 		int itid = atoi(p);
-		p = strtok(NULL,":"); //for easy continue don,t read p after this
+		p = strtok(NULL,":"); //for easy continue don't read 'p' after this
 		if(itid <= 0) continue; //silent
 		if(itemdb_exists(itid)== NULL) {
 			ShowWarning("Invalid reqIt=%d specified for skillid=%d\n",itid,skill_id);
@@ -18820,7 +18821,8 @@ static bool skill_parse_row_copyabledb(char* split[], int column, int current) {
 	skill_db[idx].copyable.reproduce = (option&2) ? true : false;
 
 	skill_db[idx].copyable.joballowed = (atoi(split[2])) ? cap_value(atoi(split[2]),1,63) : 63;
-	skill_db[idx].copyable.req_opt = cap_value(atoi(split[3]),0,4095);
+	
+	skill_db[idx].copyable.req_opt = cap_value(atoi(split[3]),0,(0x2000)-1);
 
 	return true;
 }

+ 3 - 2
src/map/skill.h

@@ -105,6 +105,7 @@ enum e_skill_display {
 
 #define MAX_SKILL_ITEM_REQUIRE	10
 #define MAX_SKILL_STATUS_REQUIRE 3
+#define MAX_SKILL_EQUIP_REQUIRE 10
 struct skill_condition {
 	int hp,
 		mhp,
@@ -119,7 +120,7 @@ struct skill_condition {
 		spiritball,
 		itemid[MAX_SKILL_ITEM_REQUIRE],
 		amount[MAX_SKILL_ITEM_REQUIRE],
-		eqItem[10]; //max eq_item
+		eqItem[MAX_SKILL_EQUIP_REQUIRE]; //max eq_item
 	uint8 status_count;
 	enum sc_type status[MAX_SKILL_STATUS_REQUIRE];
 };
@@ -138,7 +139,7 @@ struct s_skill_require {
 		spiritball[MAX_SKILL_LEVEL],
 		itemid[MAX_SKILL_ITEM_REQUIRE],
 		amount[MAX_SKILL_ITEM_REQUIRE],
-		eqItem[10]; //max eq_item
+		eqItem[MAX_SKILL_EQUIP_REQUIRE]; //max eq_item
 	uint8 status_count;
 	enum sc_type status[MAX_SKILL_STATUS_REQUIRE];
 };

+ 1 - 1
src/map/status.c

@@ -6988,7 +6988,7 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
 		else if (sc->data[SC_SIEGFRIED])
 			sc_def += sc->data[SC_SIEGFRIED]->val3*100; // Status resistance.
 		else if (sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 2)
-			sc_def += sc->data[SC_SIEGFRIED]->val3*100;
+			sc_def += sc->data[SC_SHIELDSPELL_REF]->val3*100;
 	}
 
 	// When tick def not set, reduction is the same for both.