Pārlūkot izejas kodu

-Update doc/souce_doc.txt for refactoring change
-Add doc/packet_interserv.txt and doc/packet_client.txt, to refer packets
-Upd src inner documentation, map/intif mostly
-Add common::utils::check_filepath(), fixing bugreport:9131 @loadnpc crash
-Fix pc_level_penalty_mod not using mob_class correctly
-Fix db/import/ for produce, arrow, abra, impro db...
-Upd install script (config.pl) to use mariadb for fedora/centos distrib

lighta 10 gadi atpakaļ
vecāks
revīzija
402170c018

+ 11 - 0
doc/packet_client.txt

@@ -0,0 +1,11 @@
+//===== rAthena Documentation ================================
+//= Source Documentation
+//===== By: ==================================================
+//= rAthena Dev Team
+//===== Last Updated: ========================================
+//= 20140718
+//===== Description: =========================================
+//= List of all packet used by login-serv (A), char-serv (H), map-serv (Z)
+//= to communicate to client.
+//= See packet_interserv.txt for communication between servers 
+//============================================================

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
doc/packet_interserv.txt


+ 11 - 4
doc/source_doc.txt

@@ -218,10 +218,13 @@ The following list describes each module and its purpose.
 
   Module         Description
   ------         -----------
-  account        persistence for account data
-  ipban          offers IP banishment
-  login          main module of login-serv
-  loginlog       records all operations into log for login-serv
+  account            persistence for account data
+  ipban              offers IP banishment
+  login              main module of login-serv
+  loginclif          client <=> login-serv connections interface (send and receive packets to/from client)
+  loginchrif         char-serv <=> login-serv connections interface (send and receive packets to char-serv)
+  logincsnlif        console <=> login-serv connections interface (send and receive packets to/from console (internal buffer))
+  loginlog           records all operations into log for login-serv
 
   =============
   | Char-serv |
@@ -234,6 +237,10 @@ The following list describes each module and its purpose.
   Module             Description
   ------             -----------
   char               currently holds all the char-serv (EA) process
+  -- char_clif       client <=> char-serv connections interface (send and receive packets to/from client)
+  -- char_csnlif     console <=> char-serv connections interface (send and receive packets to/from console (internal buffer))
+  -- char_mapif      map-serv <=> char-serv connections interface (send and receive packets to map-serv)
+  -- char_logif      login-serv <=> char-serv connections interface (send and receive packets to login-serv)
   inter              main entry to inter-serv; delegates packet handling to submodules
   -- int_auction     handles auction request and saving
   -- int_elemental   handles elemental data (BL_ELE => Sorcerer mob)

+ 22 - 3
src/char/int_guild.c

@@ -1456,7 +1456,17 @@ int mapif_parse_GuildBasicInfoChange(int fd,int guild_id,int type,const char *da
 	return 0;
 }
 
-// Modification of the guild
+/**
+ * Receive a modification request for the guildmember
+ * @param fd : map-serv link
+ * @param guild_id : Guild to alter
+ * @param account_id : Player aid to alter 
+ * @param char_id : Player cid to alter
+ * @param type : Type of modification
+ * @param data : Value of modification
+ * @param len : Size of value
+ * @return 
+ */
 int mapif_parse_GuildMemberInfoChange(int fd,int guild_id,int account_id,int char_id,int type,const char *data,int len)
 {
 	// Could make some improvement in speed, because only change guild_member
@@ -1662,7 +1672,16 @@ static int mapif_parse_GuildDeleteAlliance(struct guild *g, int guild_id, int ac
 	return 0;
 }
 
-// Alliance modification
+/**
+ * Alliance modification
+ * @param fd
+ * @param guild_id1
+ * @param guild_id2
+ * @param account_id1
+ * @param account_id2
+ * @param flag
+ * @return 
+ */
 int mapif_parse_GuildAlliance(int fd,int guild_id1,int guild_id2,int account_id1,int account_id2,int flag)
 {
 	// Could speed up
@@ -1710,7 +1729,7 @@ int mapif_parse_GuildAlliance(int fd,int guild_id1,int guild_id2,int account_id1
 	// Mark the two guild to be saved
 	g[0]->save_flag |= GS_ALLIANCE;
 	g[1]->save_flag |= GS_ALLIANCE;
-	return 0;
+	return 1;
 }
 
 // Change guild message

+ 6 - 1
src/char/int_party.c

@@ -740,7 +740,12 @@ int mapif_parse_PartyLeaderChange(int fd,int party_id,int account_id,int char_id
 	return 1;
 }
 
-//Used to update party share level range in run time
+/**
+ * Used to update party share level range in run time
+ * @param fd : map-serv link
+ * @param share_lvl : Max level number of difference to share exp
+ * @return 
+ */
 int mapif_parse_PartyShareLevel(int fd,unsigned int share_lvl)
 {
 	struct party_data *p;

+ 31 - 1
src/common/utils.c

@@ -64,7 +64,7 @@ void ShowDump(const void* buffer, size_t length)
 
 	ShowDebug("--- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F   0123456789ABCDEF\n");
 	ascii[16] = 0;
-
+        
 	for( i = 0; i < length; i++ )
 	{
 		char c = RBUFB(buffer,i);
@@ -145,10 +145,40 @@ void findfile(const char *p, const char *pat, void (func)(const char*))
 	}
 	return;
 }
+
+int check_filepath(const char* filepath){
+	DWORD Attribute;
+	if( Attribute = GetFileAttributes(filepath) ){
+		if( (Attribute & INVALID_FILE_ATTRIBUTES) && GetLastError() == ERROR_FILE_NOT_FOUND ) return 3;
+		else if( Attribute & FILE_ATTRIBUTE_DIRECTORY ) return 1;
+		else return 2;
+	}
+	return 0;
+}
+
 #else
 
 #define MAX_DIR_PATH 2048
 
+
+/**
+ * Check if the path is a directory or file
+ * @param filepath
+ * @return 1=dir, 2=file, 3=else, 0=error
+ */
+int check_filepath(const char* filepath){
+    struct stat s;
+
+    if( stat(filepath,&s) == 0 ){
+            if( s.st_mode & S_IFDIR ) return 1;
+            else if( s.st_mode & S_IFREG )return 2;
+            else return 3;
+    }
+    else  {
+        return 0;
+    }
+}
+
 static char* checkpath(char *path, const char*srcpath)
 {	// just make sure the char*path is not const
 	char *p=path;

+ 1 - 0
src/common/utils.h

@@ -11,6 +11,7 @@
 void WriteDump(FILE* fp, const void* buffer, size_t length);
 void ShowDump(const void* buffer, size_t length);
 
+int check_filepath(const char* filepath);
 void findfile(const char *p, const char *pat, void (func)(const char*));
 bool exists(const char* filename);
 

+ 7 - 12
src/map/atcommand.c

@@ -4454,27 +4454,22 @@ ACMD_FUNC(hidenpc)
 
 ACMD_FUNC(loadnpc)
 {
-	FILE *fp;
-
 	if (!message || !*message) {
 		clif_displaymessage(fd, msg_txt(sd,1132)); // Please enter a script file name (usage: @loadnpc <file name>).
 		return -1;
 	}
 
-	// check if script file exists
-	if ((fp = fopen(message, "r")) == NULL) {
-		clif_displaymessage(fd, msg_txt(sd,261));
-		return -1;
-	}
-	fclose(fp);
-
 	// add to list of script sources and run it
-	npc_addsrcfile(message);
-	npc_parsesrcfile(message,true);
+        if( !npc_addsrcfile(message)  //try to read file
+            || !npc_parsesrcfile(message,true)
+        ){
+            clif_displaymessage(fd, msg_txt(sd,261));
+            return -1;
+        }	
+	
 	npc_read_event_script();
 
 	clif_displaymessage(fd, msg_txt(sd,262));
-
 	return 0;
 }
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 438 - 99
src/map/intif.c


+ 1 - 1
src/map/intif.h

@@ -109,7 +109,7 @@ int intif_elemental_delete(int ele_id);
 int intif_elemental_save(struct s_elemental *ele);
 
 /* @accinfo */
-void intif_request_accinfo( int u_fd, int aid, int group_lv, char* query );
+int intif_request_accinfo( int u_fd, int aid, int group_lv, char* query );
 
 int CheckForCharServer(void);
 

+ 28 - 11
src/map/npc.c

@@ -2031,8 +2031,12 @@ static void npc_clearsrcfile(void)
 	npc_src_files = NULL;
 }
 
-/// Adds a npc source file (or removes all)
-void npc_addsrcfile(const char* name)
+/**
+ * Adds a npc source file (or removes all)
+ * @param name : file to add
+ * @return 0=error, 1=sucess
+ */
+int npc_addsrcfile(const char* name)
 {
 	struct npc_src_list* file;
 	struct npc_src_list* file_prev = NULL;
@@ -2040,15 +2044,17 @@ void npc_addsrcfile(const char* name)
 	if( strcmpi(name, "clear") == 0 )
 	{
 		npc_clearsrcfile();
-		return;
+		return 1;
 	}
 
+    if(check_filepath(name)!=2) return 0; //this is not a file 
+        
 	// prevent multiple insert of source files
 	file = npc_src_files;
 	while( file != NULL )
 	{
 		if( strcmp(name, file->name) == 0 )
-			return;// found the file, no need to insert it again
+			return 0;// found the file, no need to insert it again
 		file_prev = file;
 		file = file->next;
 	}
@@ -2060,6 +2066,8 @@ void npc_addsrcfile(const char* name)
 		npc_src_files = file;
 	else
 		file_prev->next = file;
+        
+        return 1;
 }
 
 /// Removes a npc source file (or all)
@@ -3780,9 +3788,13 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
 	return strchr(start,'\n');// continue
 }
 
-//Read file and create npc/func/mapflag/monster... accordingly.
-//@runOnInit should we exec OnInit when it's done ?
-void npc_parsesrcfile(const char* filepath, bool runOnInit)
+/**
+ * Read file and create npc/func/mapflag/monster... accordingly.
+ * @param filepath : Relative path of file from map-serv bin
+ * @param runOnInit :  should we exec OnInit when it's done ?
+ * @return 0:error, 1:success
+ */
+int npc_parsesrcfile(const char* filepath, bool runOnInit)
 {
 	int16 m, x, y;
 	int lines = 0;
@@ -3791,12 +3803,17 @@ void npc_parsesrcfile(const char* filepath, bool runOnInit)
 	char* buffer;
 	const char* p;
 
+	if(check_filepath(filepath)!=2) { //this is not a file 
+		ShowDebug("npc_parsesrcfile: Path doesn't seem to be a file skipping it : '%s'.\n", filepath);
+		return 0;
+	} 
+            
 	// read whole file to buffer
 	fp = fopen(filepath, "rb");
 	if( fp == NULL )
 	{
 		ShowError("npc_parsesrcfile: File not found '%s'.\n", filepath);
-		return;
+		return 0;
 	}
 	fseek(fp, 0, SEEK_END);
 	len = ftell(fp);
@@ -3809,7 +3826,7 @@ void npc_parsesrcfile(const char* filepath, bool runOnInit)
 		ShowError("npc_parsesrcfile: Failed to read file '%s' - %s\n", filepath, strerror(errno));
 		aFree(buffer);
 		fclose(fp);
-		return;
+		return 0;
 	}
 	fclose(fp);
 
@@ -3821,7 +3838,7 @@ void npc_parsesrcfile(const char* filepath, bool runOnInit)
 		// More info at http://unicode.org/faq/utf_bom.html#bom5 and http://en.wikipedia.org/wiki/Byte_order_mark#UTF-8
 		ShowError("npc_parsesrcfile: Detected unsupported UTF-8 BOM in file '%s'. Stopping (please consider using another character set).\n", filepath);
 		aFree(buffer);
-		return;
+		return 0;
 	}
 
 	// parse buffer
@@ -3943,7 +3960,7 @@ void npc_parsesrcfile(const char* filepath, bool runOnInit)
 	}
 	aFree(buffer);
 
-	return;
+	return 1;
 }
 
 int npc_script_event(struct map_session_data* sd, enum npce_event type)

+ 2 - 2
src/map/npc.h

@@ -147,9 +147,9 @@ bool npc_isnear(struct block_list * bl);
 
 int npc_get_new_npc_id(void);
 
-void npc_addsrcfile(const char* name);
+int npc_addsrcfile(const char* name);
 void npc_delsrcfile(const char* name);
-void npc_parsesrcfile(const char* filepath, bool runOnInit);
+int npc_parsesrcfile(const char* filepath, bool runOnInit);
 void do_clear_npc(void);
 void do_final_npc(void);
 void do_init_npc(void);

+ 5 - 2
src/map/pc.c

@@ -10091,6 +10091,7 @@ void pc_del_talisman(struct map_session_data *sd,int count,int type)
 int pc_level_penalty_mod(struct map_session_data *sd, int mob_level, uint32 mob_class, int type)
 {
 	int diff, rate = 100, i;
+	int tmp;
 
 	nullpo_ret(sd);
 
@@ -10099,9 +10100,11 @@ int pc_level_penalty_mod(struct map_session_data *sd, int mob_level, uint32 mob_
 	if( diff < 0 )
 		diff = MAX_LEVEL + ( ~diff + 1 );
 
+	if((tmp = level_penalty[type][mob_class][diff] ) > 0 ) //use mobclass directly
+		return tmp;
+	
+	//wtf is that for ? if penalty not found use the 1st one we found ?? ̂[lighta]
 	for( i = 0; i < CLASS_ALL; i++ ) {
-		int tmp;
-
 		if( ( tmp = level_penalty[type][i][diff] ) > 0 ) {
 			rate = tmp;
 			break;

+ 67 - 33
src/map/skill.c

@@ -73,13 +73,17 @@ struct skill_usave {
 
 struct s_skill_db skill_db[MAX_SKILL_DB];
 struct s_skill_produce_db skill_produce_db[MAX_SKILL_PRODUCE_DB];
+int produce_count=0;
 struct s_skill_arrow_db skill_arrow_db[MAX_SKILL_ARROW_DB];
+int arrow_count=0;
 struct s_skill_abra_db skill_abra_db[MAX_SKILL_ABRA_DB];
+int abra_count=0;
 struct s_skill_improvise_db {
 	uint16 skill_id;
 	short per;//1-10000
 };
 struct s_skill_improvise_db skill_improvise_db[MAX_SKILL_IMPROVISE_DB];
+int impro_count=0;
 
 struct s_skill_changematerial_db {
 	int itemid;
@@ -88,6 +92,7 @@ struct s_skill_changematerial_db {
 	short qty_rate[5];
 };
 struct s_skill_changematerial_db skill_changematerial_db[MAX_SKILL_PRODUCE_DB];
+int chgmateriel_count=0;
 
 //Warlock
 struct s_skill_spellbook_db {
@@ -97,8 +102,10 @@ struct s_skill_spellbook_db {
 };
 
 struct s_skill_spellbook_db skill_spellbook_db[MAX_SKILL_SPELLBOOK_DB];
+int spell_count=0;
 //Guillotine Cross
 struct s_skill_magicmushroom_db skill_magicmushroom_db[MAX_SKILL_MAGICMUSHROOM_DB];
+int mushroom_count=0;
 
 struct s_skill_unit_layout skill_unit_layout[MAX_SKILL_UNIT_LAYOUT];
 int firewall_unit_pos;
@@ -19743,21 +19750,25 @@ static bool skill_parse_row_unitdb(char* split[], int columns, int current) {
 * ProduceItemID,ItemLV,RequireSkill,Requireskill_lv,MaterialID1,MaterialAmount1,......
 */
 static bool skill_parse_row_producedb(char* split[], int columns, int current) {
-	int x,y;
+	int x,y,j;
 
 	int i = atoi(split[0]);
 	if( !i )
 		return false;
-
-	skill_produce_db[current].nameid = i;
-	skill_produce_db[current].itemlv = atoi(split[1]);
-	skill_produce_db[current].req_skill = atoi(split[2]);
-	skill_produce_db[current].req_skill_lv = atoi(split[3]);
+	
+	//search if we override something, (if not j=last idx)
+	ARR_FIND(0, produce_count, j, skill_produce_db[j].nameid==i);
+	
+	skill_produce_db[j].nameid = i;
+	skill_produce_db[j].itemlv = atoi(split[1]);
+	skill_produce_db[j].req_skill = atoi(split[2]);
+	skill_produce_db[j].req_skill_lv = atoi(split[3]);
 
 	for( x = 4, y = 0; x+1 < columns && split[x] && split[x+1] && y < MAX_PRODUCE_RESOURCE; x += 2, y++ ) {
-		skill_produce_db[current].mat_id[y] = atoi(split[x]);
-		skill_produce_db[current].mat_amount[y] = atoi(split[x+1]);
+		skill_produce_db[j].mat_id[y] = atoi(split[x]);
+		skill_produce_db[j].mat_amount[y] = atoi(split[x+1]);
 	}
+	if(j==produce_count) produce_count++;
 
 	return true;
 }
@@ -19766,18 +19777,21 @@ static bool skill_parse_row_producedb(char* split[], int columns, int current) {
 * SourceID,MakeID1,MakeAmount1,...,MakeID5,MakeAmount5
 */
 static bool skill_parse_row_createarrowdb(char* split[], int columns, int current) {
-	int x,y;
+	int x,y,j;
 
 	int i = atoi(split[0]);
 	if( !i )
 		return false;
 
-	skill_arrow_db[current].nameid = i;
-
+	//search if we override something, (if not j=last idx)
+	ARR_FIND(0, arrow_count, j, skill_arrow_db[j].nameid==i);
+	
+	skill_arrow_db[j].nameid = i;
 	for( x = 1, y = 0; x+1 < columns && split[x] && split[x+1] && y < MAX_ARROW_RESOURCE; x += 2, y++ ) {
-		skill_arrow_db[current].cre_id[y] = atoi(split[x]);
-		skill_arrow_db[current].cre_amount[y] = atoi(split[x+1]);
+		skill_arrow_db[j].cre_id[y] = atoi(split[x]);
+		skill_arrow_db[j].cre_amount[y] = atoi(split[x+1]);
 	}
+	if(j==arrow_count) arrow_count++;
 
 	return true;
 }
@@ -19786,7 +19800,8 @@ static bool skill_parse_row_createarrowdb(char* split[], int columns, int curren
 * SkillID,PreservePoints
 */
 static bool skill_parse_row_spellbookdb(char* split[], int columns, int current) {
-
+	int j;
+	
 	uint16 skill_id = atoi(split[0]);
 	int points = atoi(split[1]);
 	unsigned short nameid = atoi(split[2]);
@@ -19798,12 +19813,16 @@ static bool skill_parse_row_spellbookdb(char* split[], int columns, int current)
 	if( points < 1 )
 		ShowError("spellbook_db: PreservePoints have to be 1 or above! (%d/%s)\n", skill_id, skill_get_name(skill_id));
 	else {
-		skill_spellbook_db[current].skill_id = skill_id;
-		skill_spellbook_db[current].point = points;
-		skill_spellbook_db[current].nameid = nameid;
+		ARR_FIND(0, spell_count, j, skill_spellbook_db[j].skill_id==skill_id);
+		
+		skill_spellbook_db[j].skill_id = skill_id;
+		skill_spellbook_db[j].point = points;
+		skill_spellbook_db[j].nameid = nameid;
 
+		if(j==spell_count) spell_count++;
 		return true;
 	}
+	
 
 	return false;
 }
@@ -19830,9 +19849,13 @@ static bool skill_parse_row_improvisedb(char* split[], int columns, int current)
 	if( current >= MAX_SKILL_IMPROVISE_DB ) {
 		ShowError("skill_improvise_db: Maximum amount of entries reached (%d), increase MAX_SKILL_IMPROVISE_DB\n",MAX_SKILL_IMPROVISE_DB);
 	}
-	skill_improvise_db[current].skill_id = skill_id;
-	skill_improvise_db[current].per = j; // Still need confirm it.
-
+	ARR_FIND(0, impro_count, j, skill_improvise_db[j].skill_id==skill_id);
+	
+	skill_improvise_db[j].skill_id = skill_id;
+	skill_improvise_db[j].per = j; // Still need confirm it.
+	
+	if(j==impro_count) impro_count++;
+	
 	return true;
 }
 
@@ -19840,6 +19863,7 @@ static bool skill_parse_row_improvisedb(char* split[], int columns, int current)
 * SkillID
 */
 static bool skill_parse_row_magicmushroomdb(char* split[], int column, int current) {
+	int j;
 	uint16 skill_id = atoi(split[0]);
 
 	if( !skill_get_index(skill_id) || !skill_get_max(skill_id) )
@@ -19852,8 +19876,11 @@ static bool skill_parse_row_magicmushroomdb(char* split[], int column, int curre
 		ShowError("magicmushroom_db: Passive skills cannot be casted (%d/%s)\n", skill_id, skill_get_name(skill_id));
 		return false;
 	}
-
-	skill_magicmushroom_db[current].skill_id = skill_id;
+	ARR_FIND(0, mushroom_count, j, skill_magicmushroom_db[j].skill_id==skill_id);
+	
+	skill_magicmushroom_db[j].skill_id = skill_id;
+	
+	if(j==mushroom_count) mushroom_count++;
 
 	return true;
 }
@@ -19916,6 +19943,7 @@ static bool skill_parse_row_nonearnpcrangedb(char* split[], int column, int curr
 * SkillID,DummyName,RatePerLvl
 */
 static bool skill_parse_row_abradb(char* split[], int columns, int current) {
+	int j;
 	uint16 skill_id = atoi(split[0]);
 	if( !skill_get_index(skill_id) || !skill_get_max(skill_id) )
 	{
@@ -19928,9 +19956,12 @@ static bool skill_parse_row_abradb(char* split[], int columns, int current) {
 		return false;
 	}
 
-	skill_abra_db[current].skill_id = skill_id;
-	safestrncpy(skill_abra_db[current].name, trim(split[1]), sizeof(skill_abra_db[current].name)); //store dummyname
-	skill_split_atoi(split[2],skill_abra_db[current].per);
+	ARR_FIND(0, abra_count, j, skill_abra_db[j].skill_id==skill_id);
+	
+	skill_abra_db[j].skill_id = skill_id;
+	safestrncpy(skill_abra_db[j].name, trim(split[1]), sizeof(skill_abra_db[j].name)); //store dummyname
+	skill_split_atoi(split[2],skill_abra_db[j].per);
+	if(j==abra_count) abra_count++;
 
 	return true;
 }
@@ -19939,18 +19970,18 @@ static bool skill_parse_row_abradb(char* split[], int columns, int current) {
 * ProductID,BaseRate,MakeAmount1,MakeAmountRate1...,MakeAmount5,MakeAmountRate5
 */
 static bool skill_parse_row_changematerialdb(char* split[], int columns, int current) {
-	uint16 skill_id = atoi(split[0]);
+	uint16 product_id = atoi(split[0]);
 	short j = atoi(split[1]);
-	int x,y;
+	int x,y,k;
 
 	for(x=0; x<MAX_SKILL_PRODUCE_DB; x++){
-		if( skill_produce_db[x].nameid == skill_id )
+		if( skill_produce_db[x].nameid == product_id )
 			if( skill_produce_db[x].req_skill == GN_CHANGEMATERIAL )
 				break;
 	}
 
 	if( x >= MAX_SKILL_PRODUCE_DB ){
-		ShowError("changematerial_db: Not supported item ID(%d) for Change Material. \n", skill_id);
+		ShowError("changematerial_db: Not supported item ID(%d) for Change Material. \n", product_id);
 		return false;
 	}
 
@@ -19958,13 +19989,16 @@ static bool skill_parse_row_changematerialdb(char* split[], int columns, int cur
 		ShowError("skill_changematerial_db: Maximum amount of entries reached (%d), increase MAX_SKILL_PRODUCE_DB\n",MAX_SKILL_PRODUCE_DB);
 	}
 
-	skill_changematerial_db[current].itemid = skill_id;
-	skill_changematerial_db[current].rate = j;
+	ARR_FIND(0, chgmateriel_count, k, skill_changematerial_db[k].itemid==product_id);
+	
+	skill_changematerial_db[k].itemid = product_id;
+	skill_changematerial_db[k].rate = j;
 
 	for( x = 2, y = 0; x+1 < columns && split[x] && split[x+1] && y < 5; x += 2, y++ ) {
-		skill_changematerial_db[current].qty[y] = atoi(split[x]);
-		skill_changematerial_db[current].qty_rate[y] = atoi(split[x+1]);
+		skill_changematerial_db[k].qty[y] = atoi(split[x]);
+		skill_changematerial_db[k].qty_rate[y] = atoi(split[x+1]);
 	}
+	if(k==chgmateriel_count) chgmateriel_count++;
 
 	return true;
 }

+ 1 - 1
src/map/storage.c

@@ -727,7 +727,7 @@ void storage_guild_storagegettocart(struct map_session_data* sd, int index, int
  * Request to save guild storage
  * @param account_id : account requesting the save
  * @param guild_id : guild to take the guild_storage
- * @param flag : ?
+ * @param flag : 1=char quitting, close the storage
  * @return 0 : fail (no storage), 1 : success (requested)
  */
 int storage_guild_storagesave(int account_id, int guild_id, int flag)

+ 21 - 12
tools/config.pl

@@ -3,8 +3,15 @@
 #TODO list :
 #- don't always override import/file, sed grep ?
 
-use CPAN;
+use File::Basename;
+use DBI;
+use DBD::mysql;
+use YAML::XS;
+use Cwd;
+use Getopt::Long;
+use Net::Ping;
 use strict;
+
 use constant {
     SERV_UID => "Serv_userid",
     SERV_PW => "Serv_userpass",
@@ -28,13 +35,14 @@ use constant {
     MIN_PORT => 2000, #below are usually reserved for system
     MAX_PORT => 65535,
 };
-BEGIN { #check and install module
-    my @aCheckModule = ("File::Basename","DBI","DBD::mysql","YAML","YAML::XS","Cwd","Getopt::Long","Net::Ping");
-    my @aMarkInst = ();
-    foreach(@aCheckModule) { eval "require $_" or push(@aMarkInst,$_); }
-    CPAN::install("@aMarkInst") if(@aMarkInst > 0);
-    foreach(@aCheckModule) { $_->import(); }
-}
+#BEGIN { #check and install module
+#    my @aCheckModule = ("File::Basename","DBI","DBD::mysql","YAML","YAML::XS","Cwd","Getopt::Long","Net::Ping");
+#    my @aMarkInst = ();
+#    foreach(@aCheckModule) { eval "require $_" or push(@aMarkInst,$_); }
+#    CPAN::install("@aMarkInst") if(@aMarkInst > 0);
+#    foreach(@aCheckModule) { $_->import(); }
+#}
+
 # setup my defaults option
 my $sDsdFile    = DESD_CONF_FILE;
 my $sAutoyes    = 0;
@@ -186,13 +194,14 @@ sub InstallSoft {
     print "This autoinstall feature is experimental, package name varies from distri and version, couldn't support them all\n";
     $sOS = GetOS();
     if($sOS eq "quit"){ print "Skipping Software installation\n"; return; }
-    elsif($sOS =~ /Ubuntu|Debian/i) { #tested on ubuntu 12.10
+    elsif($sOS =~ /Ubuntu|Debian/i) { #tested on ubuntu 12.10,13.10
 	my @aListSoft = ("gcc","gdb","zlibc","zlib1g-dev","make","git","mysql-client","mysql-server","mysql-common","libmysqlclient-dev","phpmyadmin","libpcre3-dev");
 	print "Going to install: @aListSoft\n";
 	system("sudo apt-get install @aListSoft");
-    }
-    elsif($sOS =~ /Fedora|CentOs/i){ #tested on fedora 18 /centos 6
-	my @aListSoft = ("gcc","gdb","zlib","zlib-devel","make","git","mysql-server","mysql-devel","phpmyadmin","pcre-devel");
+	}
+	elsif($sOS =~ /Fedora|CentOs/i){ #tested on fedora 18,19,20 /centos 5,6,7
+	my @aListSoft = ("gcc","gdb","zlib","zlib-devel","make","git","mariadb-server","maria","mariadb-devel","phpmyadmin","pcre-devel");
+#	my @aListSoft = ("gcc","gdb","zlib","zlib-devel","make","git","mysql-server","mysql-devel","phpmyadmin","pcre-devel");
 	system("sudo yum install @aListSoft");
     }
     elsif($sOS =~ /FreeBSD/i){ #tested on FreeBSD 9.01

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels