viewing paste Unknown #5684 | Diff

Posted on the
  1. Index: conf/msg_conf/map_msg.conf
  2. ===================================================================
  3. --- conf/msg_conf/map_msg.conf	(revision 17267)
  4. +++ conf/msg_conf/map_msg.conf	(working copy)
  5. @@ -1457,6 +1457,7 @@
  6.  1433: Your global chat is now unbinded from the '#%s' channel.
  7.  1434: You're already in the '%s' channel.
  8.  1435: You're now in the '#%s' channel for '%s'.
  9. +1436: Channel pass can't be higher then %d.
  10.  
  11.  //Custom translations
  12.  //import: conf/msg_conf/import/map_msg_eng_conf.txt
  13. Index: src/map/npc.c
  14. ===================================================================
  15. --- src/map/npc.c	(revision 17267)
  16. +++ src/map/npc.c	(working copy)
  17. @@ -2138,7 +2138,7 @@
  18.  		return strchr(start,'\n');// skip and continue
  19.  	}
  20.  
  21. -	if( m != -1 && ( x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) ) { 
  22. +	if( m != -1 && ( x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) ) {
  23.  		ShowWarning("npc_parse_warp: coordinates %d/%d are out of bounds in map %s(%dx%d), in file '%s', line '%d'\n", x, y, map[m].name, map[m].xs, map[m].ys,filepath,strline(buffer,start-buffer));
  24.  	}
  25.  
  26. @@ -2209,7 +2209,7 @@
  27.  
  28.  	if( m != -1 && ( x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) ) {
  29.  		ShowWarning("npc_parse_shop: coordinates %d/%d are out of bounds in map %s(%dx%d), in file '%s', line '%d'\n", x, y, map[m].name, map[m].xs, map[m].ys,filepath,strline(buffer,start-buffer));
  30. -	} 
  31. +	}
  32.  
  33.  	if( !strcasecmp(w2,"cashshop") )
  34.  		type = CASHSHOP;
  35. @@ -3429,7 +3429,7 @@
  36.  	else if (!strcmpi(w3,"reset"))
  37.  		map[m].flag.reset=state;
  38.  	else if (!strcmpi(w3,"nomapchannelautojoin"))
  39. -		map[m].flag.chsysnolocalaj = state;
  40. +		map[m].flag.chmautojoin = state;
  41.  	else
  42.  		ShowError("npc_parse_mapflag: unrecognized mapflag '%s' (file '%s', line '%d').\n", w3, filepath, strline(buffer,start-buffer));
  43.  
  44. Index: src/map/status.c
  45. ===================================================================
  46. --- src/map/status.c	(revision 17267)
  47. +++ src/map/status.c	(working copy)
  48. @@ -10091,7 +10091,7 @@
  49.  			int hp =  rnd()%600 + 200;
  50.  			struct block_list* src = map_id2bl(sce->val2);
  51.  			if( src && bl && bl->type == BL_MOB ){
  52. -				mob_log_damage( (TBL_MOB*)bl, src, sd || hp < status->hp ? hp : status->hp - 1 ); 
  53. +				mob_log_damage( (TBL_MOB*)bl, src, sd || hp < status->hp ? hp : status->hp - 1 );
  54.  			}
  55.  			map_freeblock_lock();
  56.  			status_fix_damage(src, bl, sd||hp<status->hp?hp:status->hp-1, 1);
  57. Index: src/map/pc.c
  58. ===================================================================
  59. --- src/map/pc.c	(revision 17267)
  60. +++ src/map/pc.c	(working copy)
  61. @@ -16,6 +16,7 @@
  62.  #include "atcommand.h" // get_atcommand_level()
  63.  #include "battle.h" // battle_config
  64.  #include "battleground.h"
  65. +#include "channel.h"
  66.  #include "chrif.h"
  67.  #include "clif.h"
  68.  #include "date.h" // is_day_of_*()
  69. @@ -1249,7 +1250,7 @@
  70.  		}
  71.  
  72.  		clif_changeoption( &sd->bl );
  73. -	} 
  74. +	}
  75.  
  76.  	return 1;
  77.  }
  78. @@ -4782,9 +4783,7 @@
  79.  			vending_closevending(sd);
  80.  		}
  81.  
  82. -		if( raChSys.local && map[sd->bl.m].channel && idb_exists(map[sd->bl.m].channel->users, sd->status.char_id) ) {
  83. -			clif_chsys_left(map[sd->bl.m].channel,sd);
  84. -		}
  85. +		channel_pcquit(sd,4); //quit map chan
  86.  	}
  87.  
  88.  	if( m < 0 )
  89. @@ -9604,7 +9603,7 @@
  90.  	FILE *fp;
  91.  	char line[24000],*p;
  92.  
  93. -    //reset
  94. +	//reset
  95.  	memset(exp_table,0,sizeof(exp_table));
  96.  	memset(max_level,0,sizeof(max_level));
  97.  
  98. @@ -9651,7 +9650,7 @@
  99.  		//Reverse check in case the array has a bunch of trailing zeros... [Skotlex]
  100.  		//The reasoning behind the -2 is this... if the max level is 5, then the array
  101.  		//should look like this:
  102. -	   //0: x, 1: x, 2: x: 3: x 4: 0 <- last valid value is at 3.
  103. +		//0: x, 1: x, 2: x: 3: x 4: 0 <- last valid value is at 3.
  104.  		while ((ui = max_level[job][type]) >= 2 && exp_table[job][type][ui-2] <= 0)
  105.  			max_level[job][type]--;
  106.  		if (max_level[job][type] < maxlv) {
  107. @@ -9762,7 +9761,7 @@
  108.  	fclose(fp);
  109.  	ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","attr_fix.txt");
  110.  
  111. -    // reset then read statspoint
  112. +	 // reset then read statspoint
  113.  	memset(statp,0,sizeof(statp));
  114.  	i=1;
  115.  
  116. Index: src/map/pc.h
  117. ===================================================================
  118. --- src/map/pc.h	(revision 17267)
  119. +++ src/map/pc.h	(working copy)
  120. @@ -499,9 +499,9 @@
  121.  	int shadowform_id;
  122.  
  123.  	/* Channel System [Ind] */
  124. -	struct raChSysCh **channels;
  125. +	struct Channel **channels;
  126.  	unsigned char channel_count;
  127. -	struct raChSysCh *gcbind;
  128. +	struct Channel *gcbind;
  129.  	bool stealth;
  130.  	unsigned char fontcolor; /* debug-only */
  131.  
  132. Index: src/map/map.c
  133. ===================================================================
  134. --- src/map/map.c	(revision 17267)
  135. +++ src/map/map.c	(working copy)
  136. @@ -48,6 +48,8 @@
  137.  #include "log.h"
  138.  #include "mail.h"
  139.  #include "cashshop.h"
  140. +#include "channel.h"
  141. +
  142.  #include <stdio.h>
  143.  #include <stdlib.h>
  144.  #include <string.h>
  145. @@ -3546,7 +3548,7 @@
  146.  	struct s_mapiterator* iter;
  147.  
  148.  	ShowStatus("Terminating...\n");
  149. -	raChSys.closing = true;
  150. +	Channel_Config.closing = true;
  151.  
  152.  	//Ladies and babies first.
  153.  	iter = mapit_getallusers();
  154. @@ -3562,8 +3564,7 @@
  155.  		ShowStatus("Cleaning up maps [%d/%d]: %s..."CL_CLL"\r", i+1, map_num, map[i].name);
  156.  		if (map[i].m >= 0) {
  157.  			map_foreachinmap(cleanup_sub, i, BL_ALL);
  158. -			if( map[i].channel != NULL )
  159. -				clif_chsys_delete((struct raChSysCh *)map[i].channel);
  160. +			channel_delete((struct Channel *)map[i].channel);
  161.  		}
  162.  	}
  163.  	ShowStatus("Cleaned up %d maps."CL_CLL"\n", map_num);
  164. @@ -3574,6 +3575,7 @@
  165.  
  166.  	do_final_atcommand();
  167.  	do_final_battle();
  168. +	do_final_channel();
  169.  	do_final_chrif();
  170.  	do_final_clif();
  171.  	do_final_npc();
  172. @@ -3876,6 +3878,7 @@
  173.  	do_init_atcommand();
  174.  	do_init_battle();
  175.  	do_init_instance();
  176. +	do_init_channel();
  177.  	do_init_chrif();
  178.  	do_init_clif();
  179.  	do_init_script();
  180. Index: src/map/map.h
  181. ===================================================================
  182. --- src/map/map.h	(revision 17267)
  183. +++ src/map/map.h	(working copy)
  184. @@ -17,7 +17,7 @@
  185.  
  186.  struct npc_data;
  187.  struct item_data;
  188. -struct raChSysCh;
  189. +struct Channel;
  190.  
  191.  enum E_MAPSERVER_ST {
  192.  	MAPSERVER_ST_RUNNING = CORE_ST_LAST,
  193. @@ -567,7 +567,7 @@
  194.  		unsigned guildlock :1;
  195.  		unsigned src4instance : 1; // To flag this map when it's used as a src map for instances
  196.  		unsigned reset :1; // [Daegaladh]
  197. -		unsigned chsysnolocalaj : 1;
  198. +		unsigned chmautojoin : 1; //prevent to auto join map channel
  199.  	} flag;
  200.  	struct point save;
  201.  	struct npc_data *npc[MAX_NPC_PER_MAP];
  202. @@ -595,7 +595,7 @@
  203.  	int instance_src_map;
  204.  
  205.  	/* rAthena Local Chat */
  206. -	struct raChSysCh *channel;
  207. +	struct Channel *channel;
  208.  };
  209.  
  210.  /// Stores information about a remote map (for multi-mapserver setups).
  211. Index: src/map/Makefile.in
  212. ===================================================================
  213. --- src/map/Makefile.in	(revision 17267)
  214. +++ src/map/Makefile.in	(working copy)
  215. @@ -17,7 +17,7 @@
  216.  	storage.o skill.o atcommand.o battle.o battleground.o \
  217.  	intif.o trade.o party.o vending.o guild.o pet.o \
  218.  	log.o mail.o date.o unit.o homunculus.o mercenary.o quest.o instance.o \
  219. -	buyingstore.o searchstore.o duel.o pc_groups.o elemental.o cashshop.o
  220. +	buyingstore.o searchstore.o duel.o pc_groups.o elemental.o cashshop.o channel.o
  221.  MAP_SQL_OBJ = $(MAP_OBJ:%=obj_sql/%) \
  222.  	obj_sql/mapreg_sql.o
  223.  MAP_H = map.h chrif.h clif.h pc.h status.h npc.h \
  224. @@ -25,7 +25,7 @@
  225.  	storage.h skill.h atcommand.h battle.h battleground.h \
  226.  	intif.h trade.h party.h vending.h guild.h pet.h \
  227.  	log.h mail.h date.h unit.h homunculus.h mercenary.h quest.h instance.h mapreg.h \
  228. -	buyingstore.h searchstore.h duel.h pc_groups.h elemental.h cashshop.h \
  229. +	buyingstore.h searchstore.h duel.h pc_groups.h elemental.h cashshop.h channel.h\
  230.  	../config/core.h ../config/renewal.h ../config/secure.h ../config/const.h \
  231.  	../config/classes/general.h
  232.  
  233. @@ -91,10 +91,10 @@
  234.  # missing object files
  235.  ../common/obj_all/common.a:
  236.  	@$(MAKE) -C ../common sql
  237. -    
  238. +
  239.  ../common/obj_sql/common_sql.a:
  240.  	@$(MAKE) -C ../common sql
  241. -        
  242. +
  243.  MT19937AR_OBJ:
  244.  	@$(MAKE) -C ../../3rdparty/mt19937ar
  245.  
  246. Index: src/map/atcommand.c
  247. ===================================================================
  248. --- src/map/atcommand.c	(revision 17267)
  249. +++ src/map/atcommand.c	(working copy)
  250. @@ -17,6 +17,7 @@
  251.  #include "atcommand.h"
  252.  #include "battle.h"
  253.  #include "chat.h"
  254. +#include "channel.h"
  255.  #include "clif.h"
  256.  #include "chrif.h"
  257.  #include "duel.h"
  258. @@ -5621,28 +5622,7 @@
  259.  		status_change_start(NULL,&sd->bl, SC_AUTOTRADE, 10000, 0, 0, 0, 0, ((timeout > 0) ? min(timeout,battle_config.at_timeout) : battle_config.at_timeout) * 60000, 0);
  260.  	}
  261.  
  262. -	// Leave all chat channels.
  263. -	if( raChSys.ally && sd->status.guild_id ) {
  264. -		struct guild *g = sd->guild, *sg;
  265. -		if( g ) {
  266. -			if( idb_exists(((struct raChSysCh *)g->channel)->users, sd->status.char_id) )
  267. -				clif_chsys_left((struct raChSysCh *)g->channel,sd);
  268. -			for (i = 0; i < MAX_GUILDALLIANCE; i++) {
  269. -				if( g->alliance[i].guild_id && (sg = guild_search(g->alliance[i].guild_id) ) ) {
  270. -					if( idb_exists(((struct raChSysCh *)sg->channel)->users, sd->status.char_id) )
  271. -						clif_chsys_left((struct raChSysCh *)sg->channel,sd);
  272. -					break;
  273. -				}
  274. -			}
  275. -		}
  276. -	}
  277. -	if( sd->channel_count ) { //quit all chan
  278. -		uint8 count = sd->channel_count;
  279. -		for( i = 0; i < count; i++ ) {
  280. -			if( sd->channels[i] != NULL )
  281. -				clif_chsys_left(sd->channels[i],sd);
  282. -		}
  283. -	}
  284. +	channel_pcquit(sd,7); //leave all chan
  285.  	clif_authfail_fd(sd->fd, 15);
  286.  
  287.  	return 0;
  288. @@ -8784,25 +8764,25 @@
  289.  /* Channel System [Ind] */
  290.  ACMD_FUNC(join)
  291.  {
  292. -	struct raChSysCh *channel;
  293. -	char name[RACHSYS_NAME_LENGTH], pass[RACHSYS_NAME_LENGTH];
  294. -	DBMap* channel_db = clif_get_channel_db();
  295. +	struct Channel *channel;
  296. +	char name[CHAN_NAME_LENGTH], pass[CHAN_NAME_LENGTH];
  297. +	DBMap* channel_db = channel_get_db();
  298.  
  299.  	if( !message || !*message || sscanf(message, "%s %s", name, pass) < 1 ) {
  300.  		sprintf(atcmd_output, msg_txt(sd,1399),command); // Unknown Channel (usage: %s <#channel_name>)
  301.  		clif_displaymessage(fd, atcmd_output);
  302.  		return -1;
  303.  	}
  304. -	if( raChSys.local && strcmpi(name + 1, raChSys.local_name) == 0 ) {
  305. +	if( Channel_Config.map_enable && strcmpi(name + 1, Channel_Config.map_chname) == 0 ) {
  306.  		if( !map[sd->bl.m].channel ) {
  307. -			clif_chsys_mjoin(sd);
  308. +			channel_mjoin(sd);
  309.  			return 0;
  310.  		} else
  311.  			channel = map[sd->bl.m].channel;
  312. -	} else if( raChSys.ally && sd->status.guild_id && strcmpi(name + 1, raChSys.ally_name) == 0 ) {
  313. +	} else if( Channel_Config.ally_enable && sd->status.guild_id && strcmpi(name + 1, Channel_Config.ally_chname) == 0 ) {
  314.  		struct guild *g = sd->guild;
  315.  		if( !g ) return -1;/* unlikely, but we wont let it crash anyway. */
  316. -		channel = (struct raChSysCh *)g->channel;
  317. +		channel = (struct Channel *)g->channel;
  318.  	} else if( !( channel = strdb_get(channel_db, name + 1) ) ) {
  319.  		sprintf(atcmd_output, msg_txt(sd,1400),name,command); // Unknown Channel '%s' (usage: %s <#channel_name>)
  320.  		clif_displaymessage(fd, atcmd_output);
  321. @@ -8824,12 +8804,12 @@
  322.  		}
  323.  	}
  324.  
  325. -	if( !( channel->opt & raChSys_OPT_ANNOUNCE_JOIN ) ) {
  326. +	if( !( channel->opt & CHAN_OPT_ANNOUNCE_JOIN ) ) {
  327.  		sprintf(atcmd_output, msg_txt(sd,1403),name); // You're now in the '%s' channel.
  328.  		clif_displaymessage(fd, atcmd_output);
  329.  	}
  330.  
  331. -	clif_chsys_join(channel,sd);
  332. +	channel_join(channel,sd);
  333.  
  334.  	return 0;
  335.  }
  336. @@ -8869,164 +8849,31 @@
  337.  
  338.  ACMD_FUNC(channel)
  339.  {
  340. -	struct raChSysCh *channel;
  341. -	char key[RACHSYS_NAME_LENGTH], sub1[RACHSYS_NAME_LENGTH], sub2[RACHSYS_NAME_LENGTH], sub3[RACHSYS_NAME_LENGTH];
  342. +	struct Channel *channel;
  343. +	char key[CHAN_NAME_LENGTH], sub1[CHAN_NAME_LENGTH], sub2[CHAN_NAME_LENGTH], sub3[CHAN_NAME_LENGTH];
  344.  	unsigned char k = 0;
  345. -	DBMap* channel_db = clif_get_channel_db();
  346. +	DBMap* channel_db = channel_get_db();
  347.  	sub1[0] = sub2[0] = sub3[0] = '\0';
  348.  
  349.  	if( !message || !*message || sscanf(message, "%s %s %s %s", key, sub1, sub2, sub3) < 1 ) {
  350. -		atcmd_channel_help(sd,command,( raChSys.allow_user_channel_creation || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ));
  351. +		atcmd_channel_help(sd,command,( Channel_Config.user_chenable || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ));
  352.  		return 0;
  353.  	}
  354.  
  355. -	if( strcmpi(key,"create") == 0 && ( raChSys.allow_user_channel_creation || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ) ) {
  356. -		if( sub1[0] != '#' ) {
  357. -			clif_displaymessage(fd, msg_txt(sd,1405));// Channel name must start with '#'.
  358. -			return -1;
  359. -		} else if ( strlen(sub1) < 3 || strlen(sub1) > RACHSYS_NAME_LENGTH ) {
  360. -			sprintf(atcmd_output, msg_txt(sd,1406), RACHSYS_NAME_LENGTH);// Channel length must be between 3 and %d.
  361. -			clif_displaymessage(fd, atcmd_output);
  362. -			return -1;
  363. -		} else if ( sub3[0] != '\0' ) {
  364. -			clif_displaymessage(fd, msg_txt(sd,1408)); // Channel password may not contain spaces.
  365. -			return -1;
  366. -		}
  367. -		if( strcmpi(sub1 + 1,raChSys.local_name) == 0 || strcmpi(sub1 + 1,raChSys.ally_name) == 0 || strdb_exists(channel_db, sub1 + 1) ) {
  368. -			sprintf(atcmd_output, msg_txt(sd,1407), sub1);// Channel '%s' is not available.
  369. -			clif_displaymessage(fd, atcmd_output);
  370. -			return -1;
  371. -		}
  372. -
  373. -		CREATE( channel, struct raChSysCh, 1 );
  374. -
  375. -		clif_chsys_create(channel,sub1 + 1,sub2,0);
  376. -
  377. -		channel->owner = sd->status.char_id;
  378. -		channel->type = raChSys_PRIVATE;
  379. -
  380. -		if( !( channel->opt & raChSys_OPT_ANNOUNCE_JOIN ) ) {
  381. -			sprintf(atcmd_output, msg_txt(sd,1403),sub1); // You're now in the '%s' channel.
  382. -			clif_displaymessage(fd, atcmd_output);
  383. -		}
  384. -
  385. -		clif_chsys_join(channel,sd);
  386. -
  387. +	if( strcmpi(key,"create") == 0 && ( Channel_Config.user_chenable || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ) ) {
  388. +		return channel_pccreate(sd,sub1,sub2);
  389.  	} else if ( strcmpi(key,"list") == 0 ) {
  390. -		if( sub1[0] != '\0' && strcmpi(sub1,"colors") == 0 ) {
  391. -			char mout[40];
  392. -			for( k = 0; k < raChSys.colors_count; k++ ) {
  393. -				unsigned short msg_len = 1;
  394. -				msg_len += sprintf(mout, "[ %s list colors ] : %s",command,raChSys.colors_name[k]);
  395. -
  396. -				WFIFOHEAD(fd,msg_len + 12);
  397. -				WFIFOW(fd,0) = 0x2C1;
  398. -				WFIFOW(fd,2) = msg_len + 12;
  399. -				WFIFOL(fd,4) = 0;
  400. -				WFIFOL(fd,8) = raChSys.colors[k];
  401. -				safestrncpy((char*)WFIFOP(fd,12), mout, msg_len);
  402. -				WFIFOSET(fd, msg_len + 12);
  403. -			}
  404. -		} else {
  405. -			DBIterator *iter;
  406. -			bool show_all = pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ? true : false;
  407. -			clif_displaymessage(fd, msg_txt(sd,1410)); // ---- Public Channels ----
  408. -			if( raChSys.local ) {
  409. -				sprintf(atcmd_output, msg_txt(sd,1409), raChSys.local_name, map[sd->bl.m].channel ? db_size(map[sd->bl.m].channel->users) : 0);// - #%s ( %d users )
  410. -				clif_displaymessage(fd, atcmd_output);
  411. -			}
  412. -			if( raChSys.ally && sd->status.guild_id ) {
  413. -				struct guild *g = sd->guild;
  414. -				if( !g ) return -1;
  415. -				sprintf(atcmd_output, msg_txt(sd,1409), raChSys.ally_name, db_size(((struct raChSysCh *)g->channel)->users));// - #%s ( %d users )
  416. -				clif_displaymessage(fd, atcmd_output);
  417. -			}
  418. -			iter = db_iterator(channel_db);
  419. -			for(channel = dbi_first(iter); dbi_exists(iter); channel = dbi_next(iter)) {
  420. -				if( show_all || channel->type == raChSys_PUBLIC ) {
  421. -					sprintf(atcmd_output, msg_txt(sd,1409), channel->name, db_size(channel->users));// - #%s (%d users)
  422. -					clif_displaymessage(fd, atcmd_output);
  423. -				}
  424. -			}
  425. -			dbi_destroy(iter);
  426. -		}
  427. +		return channel_display_list(sd,sub1);
  428.  	} else if ( strcmpi(key,"setcolor") == 0 ) {
  429. -
  430. -		if( sub1[0] != '#' ) {
  431. -			clif_displaymessage(fd, msg_txt(sd,1405));// Channel name must start with '#'.
  432. -			return -1;
  433. -		}
  434. -
  435. -		if( !(channel = strdb_get(channel_db, sub1 + 1)) ) {
  436. -			sprintf(atcmd_output, msg_txt(sd,1407), sub1);// Channel '%s' is not available.
  437. -			clif_displaymessage(fd, atcmd_output);
  438. -			return -1;
  439. -		}
  440. -
  441. -		if( channel->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ) {
  442. -			sprintf(atcmd_output, msg_txt(sd,1412), sub1);// You're not the owner of channel '%s'.
  443. -			clif_displaymessage(fd, atcmd_output);
  444. -			return -1;
  445. -		}
  446. -
  447. -		for( k = 0; k < raChSys.colors_count; k++ ) {
  448. -			if( strcmpi(sub2,raChSys.colors_name[k]) == 0 )
  449. -				break;
  450. -		}
  451. -		if( k == raChSys.colors_count ) {
  452. -			sprintf(atcmd_output, msg_txt(sd,1411), sub2);// Unknown color '%s'.
  453. -			clif_displaymessage(fd, atcmd_output);
  454. -			return -1;
  455. -		}
  456. -		channel->color = k;
  457. -		sprintf(atcmd_output, msg_txt(sd,1413),sub1,raChSys.colors_name[k]);// '%s' channel color updated to '%s'.
  458. -		clif_displaymessage(fd, atcmd_output);
  459. +		return channel_pccolor(sd, sub1, sub2);
  460.  	} else if ( strcmpi(key,"leave") == 0 ) {
  461. -
  462. -		if( sub1[0] != '#' ) {
  463. -			clif_displaymessage(fd, msg_txt(sd,1405));// Channel name must start with '#'.
  464. -			return -1;
  465. -		}
  466. -
  467. -		ARR_FIND(0, sd->channel_count, k, strcmpi(sub1+1,sd->channels[k]->name) == 0);
  468. -		if( k == sd->channel_count ) {
  469. -			sprintf(atcmd_output, msg_txt(sd,1425),sub1);// You're not part of the '%s' channel.
  470. -			clif_displaymessage(fd, atcmd_output);
  471. -			return -1;
  472. -		}
  473. -		clif_chsys_left(sd->channels[k],sd);
  474. -		sprintf(atcmd_output, msg_txt(sd,1426),sub1); // You've left the '%s' channel.
  475. -		clif_displaymessage(fd, atcmd_output);
  476. +		return channel_leave(sd, sub1);
  477.  	} else if ( strcmpi(key,"bindto") == 0 ) {
  478. -
  479. -		if( sub1[0] != '#' ) {
  480. -			clif_displaymessage(fd, msg_txt(sd,1405));// Channel name must start with '#'.
  481. -			return -1;
  482. -		}
  483. -
  484. -		ARR_FIND(0, sd->channel_count, k, strcmpi(sub1+1,sd->channels[k]->name) == 0);
  485. -		if( k == sd->channel_count ) {
  486. -			sprintf(atcmd_output, msg_txt(sd,1425),sub1);// You're not part of the '%s' channel.
  487. -			clif_displaymessage(fd, atcmd_output);
  488. -			return -1;
  489. -		}
  490. -
  491. -		sd->gcbind = sd->channels[k];
  492. -		sprintf(atcmd_output, msg_txt(sd,1431),sub1); // Your global chat is now binded to the '%s' channel.
  493. -		clif_displaymessage(fd, atcmd_output);
  494. +		return channel_pcbind(sd, sub1);
  495.  	} else if ( strcmpi(key,"unbind") == 0 ) {
  496. -
  497. -		if( sd->gcbind == NULL ) {
  498. -			clif_displaymessage(fd, msg_txt(sd,1432));// Your global chat is not binded to any channel.
  499. -			return -1;
  500. -		}
  501. -
  502. -		sprintf(atcmd_output, msg_txt(sd,1433),sd->gcbind->name); // Your global chat is now unbinded from the '#%s' channel.
  503. -		clif_displaymessage(fd, atcmd_output);
  504. -
  505. -		sd->gcbind = NULL;
  506. +		return channel_pcunbind(sd);
  507.  	} else {
  508. -		atcmd_channel_help(sd,command,( raChSys.allow_user_channel_creation || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ));
  509. +		atcmd_channel_help(sd,command,( Channel_Config.user_chenable || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ));
  510.  	}
  511.  
  512.  	return 0;
  513. @@ -9038,17 +8885,9 @@
  514.  
  515.  	if( !message || !*message ) {
  516.  		char mout[40];
  517. -		for( k = 0; k < raChSys.colors_count; k++ ) {
  518. -			unsigned short msg_len = 1;
  519. -			msg_len += sprintf(mout, "[ %s ] : %s",command,raChSys.colors_name[k]);
  520. -
  521. -			WFIFOHEAD(fd,msg_len + 12);
  522. -			WFIFOW(fd,0) = 0x2C1;
  523. -			WFIFOW(fd,2) = msg_len + 12;
  524. -			WFIFOL(fd,4) = 0;
  525. -			WFIFOL(fd,8) = raChSys.colors[k];
  526. -			safestrncpy((char*)WFIFOP(fd,12), mout, msg_len);
  527. -			WFIFOSET(fd, msg_len + 12);
  528. +		for( k = 0; k < Channel_Config.colors_count; k++ ) {
  529. +			sprintf(mout, "[ %s ] : %s",command,Channel_Config.colors_name[k]);
  530. +			clif_colormes(sd,k,mout);
  531.  		}
  532.  		return -1;
  533.  	}
  534. @@ -9059,11 +8898,8 @@
  535.  		return 0;
  536.  	}
  537.  
  538. -	for( k = 0; k < raChSys.colors_count; k++ ) {
  539. -		if( strcmpi(message,raChSys.colors_name[k]) == 0 )
  540. -			break;
  541. -	}
  542. -	if( k == raChSys.colors_count ) {
  543. +	ARR_FIND(0,Channel_Config.colors_count,k,( strcmpi(message,Channel_Config.colors_name[k]) == 0 ));
  544. +	if( k == Channel_Config.colors_count ) {
  545.  		sprintf(atcmd_output, msg_txt(sd,1411), message);// Unknown color '%s'.
  546.  		clif_displaymessage(fd, atcmd_output);
  547.  		return -1;
  548. Index: src/map/channel.c
  549. ===================================================================
  550. --- src/map/channel.c	(revision 0)
  551. +++ src/map/channel.c	(revision 0)
  552. @@ -0,0 +1,649 @@
  553. +// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
  554. +// For more information, see LICENCE in the main folder
  555. +
  556. +#include "../common/cbasetypes.h"
  557. +#include "../common/malloc.h"
  558. +#include "../common/conf.h" //libconfig
  559. +#include "../common/showmsg.h"
  560. +#include "../common/strlib.h" //safestrncpy
  561. +#include "../common/socket.h" //set_eof
  562. +#include "../common/nullpo.h" //nullpo chk
  563. +
  564. +#include "map.h" //msg_conf
  565. +#include "clif.h" //clif_chsys_msg
  566. +#include "channel.h"
  567. +#include "pc.h"
  568. +
  569. +#include <stdio.h>
  570. +#include <stdlib.h>
  571. +
  572. +static DBMap* channel_db; // channels
  573. +DBMap* channel_get_db(void){ return channel_db; } //private or public chat
  574. +
  575. +/*
  576. + * Create *channel
  577. + * - then add it in channel_db if type not map or ally
  578. + */
  579. +struct Channel* channel_create(char *name, char *pass, unsigned char color, enum Channel_Type chantype) {
  580. +	struct Channel* channel;
  581. +	CREATE( channel, struct Channel, 1 ); //will exit on fail allocation
  582. +	channel->type = chantype;
  583. +
  584. +	channel->users = idb_alloc(DB_OPT_BASE);
  585. +	if( name )
  586. +		safestrncpy(channel->name, name, CHAN_NAME_LENGTH);
  587. +	channel->color = color;
  588. +	if( !pass )
  589. +		channel->pass[0] = '\0';
  590. +	else
  591. +		safestrncpy(channel->pass, pass, CHAN_NAME_LENGTH);
  592. +
  593. +	channel->opt = CHAN_OPT_BASE;
  594. +
  595. +	if( channel->type != CHAN_TYPE_MAP && channel->type != CHAN_TYPE_ALLY )
  596. +		strdb_put(channel_db, channel->name, channel);
  597. +	return channel;
  598. +}
  599. +
  600. +/*
  601. + * Delete *channel
  602. + * - check if ramin user in channel and make them all quit
  603. + * -@TODO add return value
  604. + */
  605. +void channel_delete(struct Channel *channel) {
  606. +	if(!channel)
  607. +		return;
  608. +	else if( db_size(channel->users) && !Channel_Config.closing ) {
  609. +		struct map_session_data *sd;
  610. +		DBIterator *iter = db_iterator(channel->users);
  611. +		for( sd = dbi_first(iter); dbi_exists(iter); sd = dbi_next(iter) ) { //for all users
  612. +			channel_clean(channel,sd); //make all quit
  613. +		}
  614. +		dbi_destroy(iter);
  615. +		if(channel->type == CHAN_TYPE_PRIVATE)  //when all quit it will call delete @FIXME only the case for private
  616. +			return;
  617. +	}
  618. +	db_destroy(channel->users);
  619. +	switch(channel->type){
  620. +	case CHAN_TYPE_MAP:
  621. +		map[channel->m].channel = NULL;
  622. +		aFree(channel);
  623. +		break;
  624. +	case CHAN_TYPE_ALLY:
  625. +		aFree(channel);
  626. +		break;
  627. +	}
  628. +	if( !Channel_Config.closing )
  629. +		strdb_remove(channel_db, channel->name);
  630. +}
  631. +
  632. +/*
  633. + * Make *sd join *channel
  634. + * - add charid to channel user list
  635. + * - add *channel to user channel list
  636. + */
  637. +void channel_join(struct Channel *channel, struct map_session_data *sd) {
  638. +	if(!channel || !sd)
  639. +		return;
  640. +	if(channel_haspc(channel,sd)) //already in here
  641. +		return;
  642. +
  643. +	RECREATE(sd->channels, struct Channel *, ++sd->channel_count);
  644. +	sd->channels[ sd->channel_count - 1 ] = channel;
  645. +	idb_put(channel->users, sd->status.char_id, sd);
  646. +
  647. +	if( sd->stealth ) {
  648. +		sd->stealth = false;
  649. +	} else if( channel->opt & CHAN_OPT_ANNOUNCE_JOIN ) {
  650. +		char message[60];
  651. +		sprintf(message, "#%s '%s' joined",channel->name,sd->status.name);
  652. +		clif_channel_msg(channel,sd,message);
  653. +	}
  654. +
  655. +	/* someone is cheating, we kindly disconnect the bastard */
  656. +	if( sd->channel_count > 200 ) {
  657. +		set_eof(sd->fd);
  658. +	}
  659. +}
  660. +
  661. +/*
  662. + * Make *sd join the map channel
  663. + * create the map_channel if not exist
  664. + */
  665. +void channel_mjoin(struct map_session_data *sd) {
  666. +	if(!sd) return;
  667. +
  668. +	if( !map[sd->bl.m].channel ) {
  669. +		map[sd->bl.m].channel = channel_create(Channel_Config.map_chname,NULL,Channel_Config.map_chcolor,CHAN_TYPE_MAP);
  670. +		map[sd->bl.m].channel->m = sd->bl.m; //associate map
  671. +	}
  672. +	channel_join(map[sd->bl.m].channel,sd);
  673. +
  674. +	if( !( map[sd->bl.m].channel->opt & CHAN_OPT_ANNOUNCE_JOIN ) ) {
  675. +		char mout[60];
  676. +		sprintf(mout, msg_txt(sd,1435),Channel_Config.map_chname,map[sd->bl.m].name); // You're now in the '#%s' channel for '%s'.
  677. +		clif_disp_onlyself(sd, mout, strlen(mout));
  678. +	}
  679. +}
  680. +
  681. +/*
  682. + * Make all member of guild g enter into allychan
  683. + */
  684. +void channel_allgjoin(struct guild *g){
  685. +	int i;
  686. +	struct map_session_data *pl_sd;
  687. +
  688. +	if(!g) return;
  689. +	for (i = 0; i < g->max_member; i++){ //load all guildmember
  690. +		pl_sd = g->member[i].sd;
  691. +		channel_gjoin(pl_sd,3);
  692. +	}
  693. +}
  694. +
  695. +/*
  696. + * Make *sd join the guild channel
  697. + * create a chan guild if not exist
  698. + */
  699. +void channel_gjoin(struct map_session_data *sd, int flag){
  700. +	struct Channel *channel;
  701. +	struct guild *g;
  702. +	int i;
  703. +
  704. +	if(!sd) return;
  705. +
  706. +	g = sd->guild;
  707. +	if(!g) return;
  708. +
  709. +	channel = g->channel;
  710. +	if(!channel){
  711. +		channel = channel_create(Channel_Config.ally_chname,NULL,Channel_Config.ally_chcolor,CHAN_TYPE_ALLY);
  712. +		g->channel = channel;
  713. +	}
  714. +	if(flag&1) channel_join(channel,sd);	//join our guild chat
  715. +	if(flag&2){				//join allies chat
  716. +		for (i = 0; i < MAX_GUILDALLIANCE; i++){
  717. +			struct guild *ag;
  718. +			int gid = g->alliance[i].guild_id;
  719. +			if(gid && (ag=guild_search(gid)) )
  720. +				channel_join(ag->channel,sd);
  721. +		}
  722. +	}
  723. +}
  724. +
  725. +/*
  726. + * Make *sd leave *channel and cleanup association.
  727. + * if no one remain in chat delete it (PRIVATE only atm)
  728. + */
  729. +void channel_clean(struct Channel *channel, struct map_session_data *sd) {
  730. +	unsigned char i;
  731. +
  732. +	if(!channel || !sd)
  733. +		return;
  734. +
  735. +	if( channel == sd->gcbind )
  736. +		sd->gcbind = NULL;
  737. +
  738. +	ARR_FIND(0, sd->channel_count, i, sd->channels[i] == channel);
  739. +	if( i < sd->channel_count ) {
  740. +		unsigned char cursor = i;
  741. +		sd->channels[i] = NULL;
  742. +		for(; i < sd->channel_count; i++ ) { //slice move list down
  743. +			if( sd->channels[i] == NULL )
  744. +				continue;
  745. +			sd->channels[cursor] = sd->channels[i];
  746. +			cursor++;
  747. +		}
  748. +		if ( !(sd->channel_count = cursor) ) { //if in no more chan delete db
  749. +			aFree(sd->channels);
  750. +			sd->channels = NULL;
  751. +		}
  752. +	}
  753. +
  754. +	idb_remove(channel->users,sd->status.char_id); //remove user for channel user list
  755. +	if( !db_size(channel->users) && channel->type == CHAN_TYPE_PRIVATE )
  756. +		channel_delete(channel);
  757. +}
  758. +
  759. +/*
  760. + *  type&1 : quit guild and ally
  761. + *  type&2 : quit all in user chan lists
  762. + *  type&4 : quit map chan
  763. + */
  764. +void channel_pcquit(struct map_session_data *sd, int type){
  765. +	int i;
  766. +
  767. +	if(!sd) return;
  768. +	// Leave all chat channels.
  769. +	if(type&1 && Channel_Config.ally_enable
  770. +		&& sd->status.guild_id
  771. +		&& !Channel_Config.closing ) //will be remove in guild_do_final
  772. +	{
  773. +		struct guild *g = sd->guild, *sg;
  774. +		if( g ) {
  775. +			if( channel_haspc(g->channel,sd) ) //leave guild chan
  776. +				channel_clean((struct Channel *)g->channel,sd);
  777. +			for (i = 0; i < MAX_GUILDALLIANCE; i++) { //leave all alliance chan
  778. +				if( g->alliance[i].guild_id && (sg = guild_search(g->alliance[i].guild_id) ) ) {
  779. +					if( channel_haspc(g->channel,sd) )
  780. +						channel_clean((struct Channel *)sg->channel,sd);
  781. +					break;
  782. +				}
  783. +			}
  784. +		}
  785. +	}
  786. +	if(type&2 && sd->channel_count ) { //quit all chan
  787. +		uint8 count = sd->channel_count;
  788. +		for( i = count-1; i >= 0; i--) { //going backward to avoid shifting
  789. +			channel_clean(sd->channels[i],sd);
  790. +		}
  791. +	}
  792. +	if(type&4 && channel_haspc(map[sd->bl.m].channel,sd)
  793. +		&& !Channel_Config.closing ) //will be remove in map_do_final
  794. +	{
  795. +		channel_clean(map[sd->bl.m].channel,sd);
  796. +	}
  797. +}
  798. +
  799. +/*
  800. + * Format *msg from *sd to send it in *channel
  801. + * Also truncate extra char if msg too long (max=RACHSYS_MSG_LENGTH)
  802. + */
  803. +void channel_send(struct Channel *channel, struct map_session_data *sd, char *msg) {
  804. +	char message[CHAN_MSG_LENGTH];
  805. +	snprintf(message, CHAN_MSG_LENGTH, "[ #%s ] %s : %s",channel->name,sd->status.name, msg);
  806. +	clif_channel_msg(channel,sd,message);
  807. +}
  808. +
  809. +/*
  810. + * Chk parameter for channel creation
  811. + * @type (bitflag)
  812. + *	1 : check name # + lenght
  813. + *	2 : check if already exist, need 1
  814. + *	4 : check pass lenght
  815. + * return
  816. + *  0 : success
  817. + *  -1 : bad chan name
  818. + *  -2 : bad chan name lenght
  819. + *  -3 : pass given too long
  820. + *  -4 : chan already exist
  821. + */
  822. +int channel_chk(char *chname, char *chpass, int type){
  823. +	if(type&1){ //check name
  824. +		if( chname[0] != '#' ) 	return -1; // Channel name must start with '#'
  825. +		if ( strlen(chname) < 3 || strlen(chname) > CHAN_NAME_LENGTH )
  826. +			return -2; // Channel length must be between 3 and %d.
  827. +		if( (type&2) && (
  828. +			strcmpi(chname + 1,Channel_Config.map_chname) == 0
  829. +			|| strcmpi(chname + 1,Channel_Config.ally_chname) == 0
  830. +			|| strdb_exists(channel_db, chname + 1) )
  831. +			) {
  832. +			return -4; // Channel '%s' already exist
  833. +		}
  834. +	}
  835. +	if (type&4 && (chpass != '\0' && strlen(chpass) > CHAN_NAME_LENGTH ) ) {
  836. +		return -3; // Channel pass can't be higher then %d.
  837. +	}
  838. +
  839. +	return 0;
  840. +}
  841. +
  842. +struct Channel* channel_name2channel(char *chname){
  843. +	struct Channel *channel;
  844. +	if(channel_chk(chname, NULL, 1)) return NULL;
  845. +	if( !(channel = strdb_get(channel_db, chname + 1)) ) {
  846. +		return NULL;
  847. +	}
  848. +	return channel;
  849. +}
  850. +
  851. +int channel_haspc(struct Channel *channel,struct map_session_data *sd){
  852. +	if(!channel || !sd) return 0;
  853. +	return (idb_exists(channel->users, sd->status.char_id))?1:0;
  854. +}
  855. +
  856. +int channel_pc_haschan(struct map_session_data *sd, struct Channel *channel){
  857. +	int k;
  858. +	if(!channel || !sd) return -2; //channel or player doesn't exist
  859. +	ARR_FIND(0, sd->channel_count, k, strcmpi(channel->name,sd->channels[k]->name) == 0);
  860. +	if( k >= sd->channel_count ) return -1;
  861. +	return k;
  862. +}
  863. +
  864. +int channel_display_list(struct map_session_data *sd, char *color){
  865. +	struct Channel *channel;
  866. +	char output[128];
  867. +	int k;
  868. +
  869. +	if(!sd)
  870. +		return 0;
  871. +
  872. +	if( color[0] != '\0' && strcmpi(color,"colors") == 0 ) {
  873. +		char msg[40];
  874. +		for( k = 0; k < Channel_Config.colors_count; k++ ) {
  875. +			sprintf(msg, "[ Channel list colors ] : %s",Channel_Config.colors_name[k]);
  876. +			clif_colormes(sd, k, msg);
  877. +		}
  878. +	} else {
  879. +		DBIterator *iter;
  880. +		bool show_all = pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ? true : false;
  881. +		clif_displaymessage(sd->fd, msg_txt(sd,1410)); // ---- Public Channels ----
  882. +		if( Channel_Config.map_enable ) {
  883. +			sprintf(output, msg_txt(sd,1409), Channel_Config.map_chname, map[sd->bl.m].channel ? db_size(map[sd->bl.m].channel->users) : 0);// - #%s ( %d users )
  884. +			clif_displaymessage(sd->fd, output);
  885. +		}
  886. +		if( Channel_Config.ally_enable && sd->status.guild_id ) {
  887. +			struct guild *g = sd->guild;
  888. +			if( !g ) return -1; //how can this happen if status.guild_id true ?
  889. +			sprintf(output, msg_txt(sd,1409), Channel_Config.ally_chname, db_size(((struct Channel *)g->channel)->users));// - #%s ( %d users )
  890. +			clif_displaymessage(sd->fd, output);
  891. +		}
  892. +		iter = db_iterator(channel_db);
  893. +		for(channel = dbi_first(iter); dbi_exists(iter); channel = dbi_next(iter)) {
  894. +			if( show_all || channel->type == CHAN_TYPE_PUBLIC ) {
  895. +				sprintf(output, msg_txt(sd,1409), channel->name, db_size(channel->users));// - #%s (%d users)
  896. +				clif_displaymessage(sd->fd, output);
  897. +			}
  898. +		}
  899. +		dbi_destroy(iter);
  900. +	}
  901. +	return 0;
  902. +}
  903. +
  904. +int channel_pccreate(struct map_session_data *sd, char *chname, char *chpass){
  905. +	struct Channel *channel;
  906. +	char output[128];
  907. +	int8 res;
  908. +
  909. +	if(!sd)
  910. +		return 0;
  911. +
  912. +	res = channel_chk(chname,chpass,7);
  913. +	if(res==0){ //succes
  914. +		channel = channel_create(chname + 1,chpass,0,CHAN_TYPE_PRIVATE);
  915. +		channel->owner = sd->status.char_id;
  916. +		channel_join(channel,sd);
  917. +		if( !( channel->opt & CHAN_OPT_ANNOUNCE_JOIN ) ) {
  918. +			sprintf(output, msg_txt(sd,1403),chname); // You're now in the '%s' channel.
  919. +			clif_displaymessage(sd->fd, output);
  920. +		}
  921. +	} else { //failure display cause
  922. +		switch(res){
  923. +		case -1: sprintf(output, msg_txt(sd,1405), CHAN_NAME_LENGTH); break;// Channel name must start with '#'.
  924. +		case -2: sprintf(output, msg_txt(sd,1406), CHAN_NAME_LENGTH); break;// Channel length must be between 3 and %d.
  925. +		case -3: sprintf(output, msg_txt(sd,1436), CHAN_NAME_LENGTH); break;// Channel pass can't be higher then %d.
  926. +		case -4: sprintf(output, msg_txt(sd,1407), chname);// Channel '%s' is not available.
  927. +		}
  928. +		clif_displaymessage(sd->fd, output);
  929. +		return -1;
  930. +	}
  931. +	return 0;
  932. +}
  933. +
  934. +int channel_leave(struct map_session_data *sd, char *chname){
  935. +	struct Channel *channel;
  936. +	char output[128];
  937. +
  938. +	if(!sd)
  939. +		return 0;
  940. +
  941. +	if( channel_chk(chname,NULL,1) ) {
  942. +		clif_displaymessage(sd->fd, msg_txt(sd,1405));// Channel name must start with '#'.
  943. +		return -1;
  944. +	}
  945. +	channel = channel_name2channel(chname);
  946. +	if(channel_pc_haschan(sd,channel)<0){
  947. +		sprintf(output, msg_txt(sd,1425),chname);// You're not part of the '%s' channel.
  948. +		clif_displaymessage(sd->fd, output);
  949. +		return -2; //channel doesn't exist or player don't have it
  950. +	}
  951. +
  952. +	if( !Channel_Config.closing && (channel->opt & CHAN_OPT_ANNOUNCE_JOIN) ) {
  953. +		char message[60];
  954. +		sprintf(message, "#%s '%s' left",channel->name,sd->status.name);
  955. +		clif_channel_msg(channel,sd,message);
  956. +	}
  957. +	channel_clean(channel,sd);
  958. +
  959. +	sprintf(output, msg_txt(sd,1426),chname); // You've left the '%s' channel.
  960. +	clif_displaymessage(sd->fd, output);
  961. +	return 0;
  962. +}
  963. +
  964. +int channel_pccolor(struct map_session_data *sd, char *chname, char *color){
  965. +	struct Channel *channel;
  966. +	char output[128];
  967. +	int k;
  968. +
  969. +	if(!sd)
  970. +		return 0;
  971. +
  972. +	if( channel_chk(chname,NULL,1) ) {
  973. +		clif_displaymessage(sd->fd, msg_txt(sd,1405));// Channel name must start with '#'.
  974. +		return -1;
  975. +	}
  976. +	channel = channel_name2channel(chname);
  977. +	if( !channel ) {
  978. +		sprintf(output, msg_txt(sd,1407), chname);// Channel '%s' is not available.
  979. +		clif_displaymessage(sd->fd, output);
  980. +		return -1;
  981. +	}
  982. +
  983. +	if( channel->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ) {
  984. +		sprintf(output, msg_txt(sd,1412), chname);// You're not the owner of channel '%s'.
  985. +		clif_displaymessage(sd->fd, output);
  986. +		return -1;
  987. +	}
  988. +
  989. +	ARR_FIND(0,Channel_Config.colors_count,k,( strcmpi(color,Channel_Config.colors_name[k]) == 0 ) );
  990. +	if( k >= Channel_Config.colors_count ) {
  991. +		sprintf(output, msg_txt(sd,1411), color);// Unknown color '%s'.
  992. +		clif_displaymessage(sd->fd, output);
  993. +		return -1;
  994. +	}
  995. +	channel->color = k;
  996. +	sprintf(output, msg_txt(sd,1413),chname,Channel_Config.colors_name[k]);// '%s' channel color updated to '%s'.
  997. +	clif_displaymessage(sd->fd, output);
  998. +	return 0;
  999. +}
  1000. +
  1001. +int channel_pcbind(struct map_session_data *sd, char *chname){
  1002. +	struct Channel *channel;
  1003. +	char output[128];
  1004. +
  1005. +	if(!sd)
  1006. +		return 0;
  1007. +
  1008. +	if( channel_chk(chname,NULL,1) ) {
  1009. +		clif_displaymessage(sd->fd, msg_txt(sd,1405));// Channel name must start with '#'.
  1010. +		return -1;
  1011. +	}
  1012. +	channel = channel_name2channel(chname);
  1013. +	if(channel_pc_haschan(sd,channel)<0){
  1014. +		sprintf(output, msg_txt(sd,1425),chname);// You're not part of the '%s' channel.
  1015. +		clif_displaymessage(sd->fd, output);
  1016. +		return -2; //channel doesn't exist or player don't have it
  1017. +	}
  1018. +	sd->gcbind = channel;
  1019. +	sprintf(output, msg_txt(sd,1431),chname); // Your global chat is now binded to the '%s' channel.
  1020. +	clif_displaymessage(sd->fd, output);
  1021. +	return 0;
  1022. +}
  1023. +
  1024. +int channel_pcunbind(struct map_session_data *sd){
  1025. +	char output[128];
  1026. +
  1027. +	if(!sd)
  1028. +		return 0;
  1029. +
  1030. +	if( sd->gcbind == NULL ) {
  1031. +		clif_displaymessage(sd->fd, msg_txt(sd,1432));// Your global chat is not binded to any channel.
  1032. +		return -1;
  1033. +	}
  1034. +	sprintf(output, msg_txt(sd,1433),sd->gcbind->name); // Your global chat is now unbinded from the '#%s' channel.
  1035. +	clif_displaymessage(sd->fd, output);
  1036. +	sd->gcbind = NULL;
  1037. +	return 0;
  1038. +}
  1039. +
  1040. +/*
  1041. + * Read and verify configuration in confif_filename
  1042. + * Assign table value with value
  1043. + */
  1044. +void channel_read_config(void) {
  1045. +	config_t channels_conf;
  1046. +	config_setting_t *chsys = NULL;
  1047. +	const char *config_filename = "conf/channels.conf"; // FIXME hardcoded name
  1048. +
  1049. +	if (conf_read_file(&channels_conf, config_filename))
  1050. +		return;
  1051. +
  1052. +	chsys = config_lookup(&channels_conf, "chsys");
  1053. +
  1054. +	if (chsys != NULL) {
  1055. +		config_setting_t *settings = config_setting_get_elem(chsys, 0);
  1056. +		config_setting_t *channels;
  1057. +		config_setting_t *colors;
  1058. +		int i,k;
  1059. +		const char *map_chname, *ally_chname,*map_color, *ally_color;
  1060. +		int ally_enabled = 0, local_enabled = 0;
  1061. +		int local_autojoin = 0, ally_autojoin = 0;
  1062. +		int allow_user_channel_creation = 0;
  1063. +
  1064. +		if( !config_setting_lookup_string(settings, "map_local_channel_name", &map_chname) )
  1065. +			map_chname = "map";
  1066. +		safestrncpy(Channel_Config.map_chname, map_chname, CHAN_NAME_LENGTH);
  1067. +
  1068. +		if( !config_setting_lookup_string(settings, "ally_channel_name", &ally_chname) )
  1069. +			ally_chname = "ally";
  1070. +		safestrncpy(Channel_Config.ally_chname, ally_chname, CHAN_NAME_LENGTH);
  1071. +
  1072. +		config_setting_lookup_bool(settings, "map_local_channel", &local_enabled);
  1073. +		config_setting_lookup_bool(settings, "ally_channel_enabled", &ally_enabled);
  1074. +
  1075. +		if( local_enabled )
  1076. +			Channel_Config.map_enable = true;
  1077. +		if( ally_enabled )
  1078. +			Channel_Config.ally_enable = true;
  1079. +
  1080. +		config_setting_lookup_bool(settings, "map_local_channel_autojoin", &local_autojoin);
  1081. +		config_setting_lookup_bool(settings, "ally_channel_autojoin", &ally_autojoin);
  1082. +
  1083. +		if( local_autojoin )
  1084. +			Channel_Config.map_autojoin = true;
  1085. +		if( ally_autojoin )
  1086. +			Channel_Config.ally_autojoin = true;
  1087. +
  1088. +		config_setting_lookup_bool(settings, "allow_user_channel_creation", &allow_user_channel_creation);
  1089. +
  1090. +		if( allow_user_channel_creation )
  1091. +			Channel_Config.user_chenable = true;
  1092. +
  1093. +		if( (colors = config_setting_get_member(settings, "colors")) != NULL ) {
  1094. +			int color_count = config_setting_length(colors);
  1095. +			CREATE( Channel_Config.colors, unsigned long, color_count );
  1096. +			CREATE( Channel_Config.colors_name, char *, color_count );
  1097. +			for(i = 0; i < color_count; i++) {
  1098. +				config_setting_t *color = config_setting_get_elem(colors, i);
  1099. +				CREATE( Channel_Config.colors_name[i], char, CHAN_NAME_LENGTH );
  1100. +
  1101. +				safestrncpy(Channel_Config.colors_name[i], config_setting_name(color), CHAN_NAME_LENGTH);
  1102. +				Channel_Config.colors[i] = strtoul(config_setting_get_string_elem(colors,i),NULL,0);
  1103. +				Channel_Config.colors[i] = (Channel_Config.colors[i] & 0x0000FF) << 16 | (Channel_Config.colors[i] & 0x00FF00) | (Channel_Config.colors[i] & 0xFF0000) >> 16;//RGB to BGR
  1104. +			}
  1105. +			Channel_Config.colors_count = color_count;
  1106. +		}
  1107. +
  1108. +		config_setting_lookup_string(settings, "map_local_channel_color", &map_color);
  1109. +
  1110. +		for (k = 0; k < Channel_Config.colors_count; k++) {
  1111. +			if( strcmpi(Channel_Config.colors_name[k],map_color) == 0 )
  1112. +				break;
  1113. +		}
  1114. +
  1115. +		if( k < Channel_Config.colors_count ) {
  1116. +			Channel_Config.map_chcolor = k;
  1117. +		} else {
  1118. +			ShowError("channels.conf: unknown color '%s' for channel 'map_local_channel_color', disabling '#%s'...\n",map_color,map_chname);
  1119. +			Channel_Config.map_enable = false;
  1120. +		}
  1121. +
  1122. +		config_setting_lookup_string(settings, "ally_channel_color", &ally_color);
  1123. +
  1124. +		for (k = 0; k < Channel_Config.colors_count; k++) {
  1125. +			if( strcmpi(Channel_Config.colors_name[k],ally_color) == 0 )
  1126. +				break;
  1127. +		}
  1128. +
  1129. +		if( k < Channel_Config.colors_count ) {
  1130. +			Channel_Config.ally_chcolor = k;
  1131. +		} else {
  1132. +			ShowError("channels.conf: unknown color '%s' for channel 'ally_channel_color', disabling '#%s'...\n",map_color,ally_chname);
  1133. +			Channel_Config.ally_enable = false;
  1134. +		}
  1135. +
  1136. +		if( (channels = config_setting_get_member(settings, "default_channels")) != NULL ) {
  1137. +			int channel_count = config_setting_length(channels);
  1138. +
  1139. +			for(i = 0; i < channel_count; i++) {
  1140. +				config_setting_t *channel = config_setting_get_elem(channels, i);
  1141. +				const char *color = config_setting_get_string_elem(channels,i);
  1142. +				char *name = config_setting_name(channel);
  1143. +				struct Channel *chd;
  1144. +
  1145. +				for (k = 0; k < Channel_Config.colors_count; k++) {
  1146. +					if( strcmpi(Channel_Config.colors_name[k],color) == 0 )
  1147. +						break;
  1148. +				}
  1149. +				if( k == Channel_Config.colors_count ) {
  1150. +					ShowError("channels.conf: unknown color '%s' for channel '%s', skipping channel...\n",color,name);
  1151. +					continue;
  1152. +				}
  1153. +				if( strcmpi(name,Channel_Config.map_chname) == 0 || strcmpi(name,Channel_Config.ally_chname) == 0 || strdb_exists(channel_db, name) ) {
  1154. +					ShowError("channels.conf: duplicate channel '%s', skipping channel...\n",name);
  1155. +					continue;
  1156. +				}
  1157. +				chd = channel_create(name,NULL,k,CHAN_TYPE_PUBLIC);
  1158. +			}
  1159. +		}
  1160. +
  1161. +		ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' channels in '"CL_WHITE"%s"CL_RESET"'.\n", db_size(channel_db), config_filename);
  1162. +		config_destroy(&channels_conf);
  1163. +	}
  1164. +}
  1165. +
  1166. +/*
  1167. + * Initialise db and read config
  1168. + */
  1169. +int do_init_channel(void) {
  1170. +	channel_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, CHAN_NAME_LENGTH);
  1171. +	Channel_Config.ally_enable = Channel_Config.map_enable = Channel_Config.ally_autojoin = Channel_Config.map_autojoin = false;
  1172. +	channel_read_config();
  1173. +	return 0;
  1174. +}
  1175. +
  1176. +/*
  1177. + * Close all and cleanup
  1178. + * NB map and guild need to cleanup their chan as well
  1179. + */
  1180. +void do_final_channel(void) {
  1181. +	DBIterator *iter;
  1182. +	struct Channel *channel;
  1183. +	int i=0;
  1184. +
  1185. +	//delete all in chan db
  1186. +	iter = db_iterator(channel_db);
  1187. +	for( channel = dbi_first(iter); dbi_exists(iter); channel = dbi_next(iter) ) {
  1188. +		channel_delete(channel);
  1189. +	}
  1190. +	dbi_destroy(iter);
  1191. +	db_destroy(channel_db);
  1192. +
  1193. +	//delete all color thing
  1194. +	if( Channel_Config.colors_count ) {
  1195. +		for(i = 0; i < Channel_Config.colors_count; i++) {
  1196. +			aFree(Channel_Config.colors_name[i]);
  1197. +		}
  1198. +		aFree(Channel_Config.colors_name);
  1199. +		aFree(Channel_Config.colors);
  1200. +	}
  1201. +}
  1202. \ No newline at end of file
  1203. Index: src/map/battle.c
  1204. ===================================================================
  1205. --- src/map/battle.c	(revision 17267)
  1206. +++ src/map/battle.c	(working copy)
  1207. @@ -3460,7 +3460,7 @@
  1208.  
  1209.  #ifdef RENEWAL
  1210.  		if( flag.cri ){
  1211. -			ATK_ADDRATE( sd->bonus.crit_atk_rate >= 100 ? sd->bonus.crit_atk_rate - 60 : 40 ); 
  1212. +			ATK_ADDRATE( sd->bonus.crit_atk_rate >= 100 ? sd->bonus.crit_atk_rate - 60 : 40 );
  1213.  		}
  1214.  #endif
  1215.  
  1216. Index: src/map/channel.h
  1217. ===================================================================
  1218. --- src/map/channel.h	(revision 0)
  1219. +++ src/map/channel.h	(revision 0)
  1220. @@ -0,0 +1,85 @@
  1221. +// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
  1222. +// For more information, see LICENCE in the main folder
  1223. +
  1224. +#ifndef CHANNEL_H
  1225. +#define	CHANNEL_H
  1226. +
  1227. +#include "pc.h"
  1228. +
  1229. +#ifdef	__cplusplus
  1230. +extern "C" {
  1231. +#endif
  1232. +
  1233. +#define CHAN_NAME_LENGTH 20
  1234. +#define CHAN_MSG_LENGTH 150
  1235. +
  1236. +enum Channel_Opt {
  1237. +	CHAN_OPT_BASE		= 0,
  1238. +	CHAN_OPT_ANNOUNCE_JOIN	= 1,	//display message when join or leave
  1239. +};
  1240. +
  1241. +enum Channel_Type {
  1242. +	CHAN_TYPE_PUBLIC	= 0,	//config file made
  1243. +	CHAN_TYPE_PRIVATE	= 1,	//user made
  1244. +	CHAN_TYPE_MAP		= 2,	//made by map
  1245. +	CHAN_TYPE_ALLY		= 3,	//guild
  1246. +};
  1247. +
  1248. +struct {
  1249. +	unsigned long *colors;		//color avail int list
  1250. +	char **colors_name;		//colors avail name list
  1251. +	unsigned char colors_count;	//color avail count
  1252. +	unsigned char map_chcolor, ally_chcolor; //msg color for map, ally
  1253. +	bool map_enable, ally_enable, user_chenable; //map, ally, users channels enable ?
  1254. +	bool map_autojoin, ally_autojoin;	//do user auto join in mapchange, guildjoin ?
  1255. +	char map_chname[CHAN_NAME_LENGTH], ally_chname[CHAN_NAME_LENGTH]; //channel name for map and ally
  1256. +	bool closing;			//server is closing
  1257. +} Channel_Config;
  1258. +
  1259. +struct Channel {
  1260. +	char name[CHAN_NAME_LENGTH];	//channel name
  1261. +	char pass[CHAN_NAME_LENGTH];	//channel password
  1262. +	unsigned char color;		//msg color
  1263. +	DBMap *users;			//user charid list
  1264. +	enum Channel_Opt opt;		//flag for some treatement
  1265. +	unsigned int owner;		//if private type charid of who create the chan,
  1266. +	enum Channel_Type type;		//type of channel
  1267. +	uint16 m;			//if map type mapid
  1268. +};
  1269. +
  1270. +DBMap* channel_get_db(void);
  1271. +
  1272. +struct Channel* channel_create(char *name, char *pass, unsigned char color, enum Channel_Type chantype);
  1273. +void channel_delete(struct Channel *channel);
  1274. +
  1275. +void channel_join(struct Channel *channel, struct map_session_data *sd);
  1276. +void channel_mjoin(struct map_session_data *sd);
  1277. +void channel_gjoin(struct map_session_data *sd, int flag);
  1278. +void channel_allgjoin(struct guild *g);
  1279. +void channel_clean(struct Channel *channel, struct map_session_data *sd);
  1280. +void channel_pcquit(struct map_session_data *sd, int type);
  1281. +
  1282. +void channel_send(struct Channel *channel, struct map_session_data *sd, char *msg);
  1283. +void channel_read_config(void);
  1284. +
  1285. +int channel_chk(char *name, char *pass, int type);
  1286. +struct Channel* channel_name2channel(char *name);
  1287. +int channel_haspc(struct Channel *channel,struct map_session_data *sd);
  1288. +int channel_pc_haschan(struct map_session_data *sd, struct Channel *channel);
  1289. +int channel_pc_haschan(struct map_session_data *sd, struct Channel *channel);
  1290. +int channel_pccolor(struct map_session_data *sd, char *name, char *color);
  1291. +int channel_display_list(struct map_session_data *sd, char *color);
  1292. +int channel_pccreate(struct map_session_data *sd, char *name, char *pass);
  1293. +int channel_leave(struct map_session_data *sd, char *name);
  1294. +int channel_pcbind(struct map_session_data *sd, char *name);
  1295. +int channel_pcunbind(struct map_session_data *sd);
  1296. +
  1297. +int do_init_channel(void);
  1298. +void do_final_channel(void);
  1299. +
  1300. +#ifdef	__cplusplus
  1301. +}
  1302. +#endif
  1303. +
  1304. +#endif	/* CHANNEL_H */
  1305. +
  1306. Index: src/map/unit.c
  1307. ===================================================================
  1308. --- src/map/unit.c	(revision 17267)
  1309. +++ src/map/unit.c	(working copy)
  1310. @@ -18,6 +18,7 @@
  1311.  #include "mercenary.h"
  1312.  #include "elemental.h"
  1313.  #include "skill.h"
  1314. +#include "channel.h"
  1315.  #include "clif.h"
  1316.  #include "duel.h"
  1317.  #include "npc.h"
  1318. @@ -2294,31 +2295,8 @@
  1319.  			if( sd->duel_invite > 0 )
  1320.  				duel_reject(sd->duel_invite, sd);
  1321.  
  1322. -			if( raChSys.ally && sd->status.guild_id ) {
  1323. -				struct guild *g = sd->guild, *sg;
  1324. -				if( g ) {
  1325. -					if( idb_exists(((struct raChSysCh *)g->channel)->users, sd->status.char_id) )
  1326. -						clif_chsys_left((struct raChSysCh *)g->channel,sd);
  1327. -					for (i = 0; i < MAX_GUILDALLIANCE; i++) {
  1328. -						if( g->alliance[i].guild_id && (sg = guild_search(g->alliance[i].guild_id) ) ) {
  1329. -							if( idb_exists(((struct raChSysCh *)sg->channel)->users, sd->status.char_id) )
  1330. -								clif_chsys_left((struct raChSysCh *)sg->channel,sd);
  1331. -							break;
  1332. -						}
  1333. -					}
  1334. -				}
  1335. -			}
  1336. +			channel_pcquit(sd,7); //leave all chan
  1337.  
  1338. -			if( sd->channel_count ) {
  1339. -				uint8 ch_count = sd->channel_count;
  1340. -				for( i = 0; i < ch_count; i++ ) {
  1341. -					if( sd->channels[i] != NULL )
  1342. -						clif_chsys_left(sd->channels[i],sd);
  1343. -				}
  1344. -				if( raChSys.closing )
  1345. -					aFree(sd->channels);
  1346. -			}
  1347. -
  1348.  			// Notify friends that this char logged out. [Skotlex]
  1349.  			map_foreachpc(clif_friendslist_toggle_sub, sd->status.account_id, sd->status.char_id, 0);
  1350.  			party_send_logout(sd);
  1351. Index: src/map/clif.c
  1352. ===================================================================
  1353. --- src/map/clif.c	(revision 17267)
  1354. +++ src/map/clif.c	(working copy)
  1355. @@ -44,6 +44,7 @@
  1356.  #include "mail.h"
  1357.  #include "quest.h"
  1358.  #include "cashshop.h"
  1359. +#include "channel.h"
  1360.  
  1361.  #include <stdio.h>
  1362.  #include <stdlib.h>
  1363. @@ -53,8 +54,6 @@
  1364.  
  1365.  /* for clif_clearunit_delayed */
  1366.  static struct eri *delay_clearunit_ers;
  1367. -static DBMap* channel_db; // channels
  1368. -DBMap* clif_get_channel_db(void){ return channel_db; }
  1369.  
  1370.  //#define DUMP_UNKNOWN_PACKET
  1371.  //#define DUMP_INVALID_PACKET
  1372. @@ -5490,52 +5489,11 @@
  1373.  		aFree(buf);
  1374.  }
  1375.  
  1376. -/*==========================================
  1377. - * Channel System
  1378. - *------------------------------------------*/
  1379. -void clif_chsys_create(struct raChSysCh *channel, char *name, char *pass, unsigned char color) {
  1380. -	channel->users = idb_alloc(DB_OPT_BASE);
  1381. -	if( name )
  1382. -		safestrncpy(channel->name, name, RACHSYS_NAME_LENGTH);
  1383. -	channel->color = color;
  1384. -	if( !pass )
  1385. -		channel->pass[0] = '\0';
  1386. -	else
  1387. -		safestrncpy(channel->pass, pass, RACHSYS_NAME_LENGTH);
  1388. -
  1389. -	channel->opt = raChSys_OPT_BASE;
  1390. -
  1391. -	if( channel->type != raChSys_MAP && channel->type != raChSys_ALLY )
  1392. -		strdb_put(channel_db, channel->name, channel);
  1393. -}
  1394. -
  1395. -void clif_chsys_join(struct raChSysCh *channel, struct map_session_data *sd) {
  1396. -	RECREATE(sd->channels, struct raChSysCh *, ++sd->channel_count);
  1397. -	sd->channels[ sd->channel_count - 1 ] = channel;
  1398. -	idb_put(channel->users, sd->status.char_id, sd);
  1399. -
  1400. -	if( sd->stealth ) {
  1401. -		sd->stealth = false;
  1402. -	} else if( channel->opt & raChSys_OPT_ANNOUNCE_JOIN ) {
  1403. -		char message[60];
  1404. -		sprintf(message, "#%s '%s' joined",channel->name,sd->status.name);
  1405. -		clif_chsys_msg(channel,sd,message);
  1406. -	}
  1407. -
  1408. -	/* someone is cheating, we kindly disconnect the bastard */
  1409. -	if( sd->channel_count > 200 ) {
  1410. -		set_eof(sd->fd);
  1411. -	}
  1412. -}
  1413. -
  1414. -void clif_chsys_send(struct raChSysCh *channel, struct map_session_data *sd, char *msg) {
  1415. -	char message[150];
  1416. -	snprintf(message, 150, "[ #%s ] %s : %s",channel->name,sd->status.name, msg);
  1417. -	clif_chsys_msg(channel,sd,message);
  1418. -}
  1419. -
  1420. -void clif_chsys_msg(struct raChSysCh *channel, struct map_session_data *sd, char *msg) {
  1421. -	DBIterator *iter = db_iterator(channel->users);
  1422. +/*
  1423. + * Display *msg from *sd to all *user in channel
  1424. + */
  1425. +void clif_channel_msg(struct Channel *channel, struct map_session_data *sd, char *msg) {
  1426. +	DBIterator *iter;
  1427.  	struct map_session_data *user;
  1428.  	unsigned short msg_len = strlen(msg) + 1;
  1429.  
  1430. @@ -5543,9 +5501,10 @@
  1431.  	WFIFOW(sd->fd,0) = 0x2C1;
  1432.  	WFIFOW(sd->fd,2) = msg_len + 12;
  1433.  	WFIFOL(sd->fd,4) = 0;
  1434. -	WFIFOL(sd->fd,8) = raChSys.colors[channel->color];
  1435. +	WFIFOL(sd->fd,8) = Channel_Config.colors[channel->color];
  1436.  	safestrncpy((char*)WFIFOP(sd->fd,12), msg, msg_len);
  1437.  
  1438. +	iter = db_iterator(channel->users);
  1439.  	for( user = dbi_first(iter); dbi_exists(iter); user = dbi_next(iter) ) {
  1440.  		if( user->fd == sd->fd )
  1441.  			continue;
  1442. @@ -5559,225 +5518,6 @@
  1443.  	dbi_destroy(iter);
  1444.  }
  1445.  
  1446. -void clif_chsys_mjoin(struct map_session_data *sd) {
  1447. -	if( !map[sd->bl.m].channel ) {
  1448. -		CREATE(map[sd->bl.m].channel, struct raChSysCh , 1);
  1449. -		safestrncpy(map[sd->bl.m].channel->name, raChSys.local_name, RACHSYS_NAME_LENGTH);
  1450. -		map[sd->bl.m].channel->type = raChSys_MAP;
  1451. -		map[sd->bl.m].channel->m = sd->bl.m;
  1452. -
  1453. -		clif_chsys_create(map[sd->bl.m].channel,NULL,NULL,raChSys.local_color);
  1454. -	}
  1455. -	clif_chsys_join(map[sd->bl.m].channel,sd);
  1456. -
  1457. -	if( !( map[sd->bl.m].channel->opt & raChSys_OPT_ANNOUNCE_JOIN ) ) {
  1458. -		char mout[60];
  1459. -		sprintf(mout, msg_txt(sd,1435),raChSys.local_name,map[sd->bl.m].name); // You're now in the '#%s' channel for '%s'.
  1460. -		clif_disp_onlyself(sd, mout, strlen(mout));
  1461. -	}
  1462. -}
  1463. -
  1464. -void clif_chsys_left(struct raChSysCh *channel, struct map_session_data *sd) {
  1465. -	unsigned char i;
  1466. -	idb_remove(channel->users,sd->status.char_id);
  1467. -
  1468. -	if( channel == sd->gcbind )
  1469. -		sd->gcbind = NULL;
  1470. -
  1471. -	if( !db_size(channel->users) && channel->type == raChSys_PRIVATE ) {
  1472. -		clif_chsys_delete(channel);
  1473. -	} else if( !raChSys.closing && (channel->opt & raChSys_OPT_ANNOUNCE_JOIN) ) {
  1474. -		char message[60];
  1475. -		sprintf(message, "#%s '%s' left",channel->name,sd->status.name);
  1476. -		clif_chsys_msg(channel,sd,message);
  1477. -	}
  1478. -
  1479. -	ARR_FIND(0, sd->channel_count, i, sd->channels[i] == channel);
  1480. -	if( i < sd->channel_count ) {
  1481. -		unsigned char cursor = 0;
  1482. -		sd->channels[i] = NULL;
  1483. -		for( i = 0; i < sd->channel_count; i++ ) {
  1484. -			if( sd->channels[i] == NULL )
  1485. -				continue;
  1486. -			if( cursor != i )
  1487. -				sd->channels[cursor] = sd->channels[i];
  1488. -			cursor++;
  1489. -		}
  1490. -		if ( !(sd->channel_count = cursor) ) {
  1491. -			aFree(sd->channels);
  1492. -			sd->channels = NULL;
  1493. -		}
  1494. -	}
  1495. -
  1496. -}
  1497. -
  1498. -void clif_chsys_delete(struct raChSysCh *channel) {
  1499. -	if( db_size(channel->users) && !raChSys.closing ) {
  1500. -		struct map_session_data *sd;
  1501. -		unsigned char i;
  1502. -		DBIterator *iter = db_iterator(channel->users);
  1503. -		for( sd = dbi_first(iter); dbi_exists(iter); sd = dbi_next(iter) ) { //for all users
  1504. -			ARR_FIND(0, sd->channel_count, i, sd->channels[i] == channel); //found cur chan
  1505. -			if( i < sd->channel_count ) {
  1506. -				unsigned char cursor = 0;
  1507. -				sd->channels[i] = NULL;
  1508. -				for( i = 0; i < sd->channel_count; i++ ) { //move down links
  1509. -					if( sd->channels[i] == NULL )
  1510. -						continue;
  1511. -					if( cursor != i )
  1512. -						sd->channels[cursor] = sd->channels[i];
  1513. -					cursor++;
  1514. -				}
  1515. -				if ( !(sd->channel_count = cursor) ) { //news chan count = total
  1516. -					aFree(sd->channels);
  1517. -					sd->channels = NULL;
  1518. -				}
  1519. -			}
  1520. -		}
  1521. -		dbi_destroy(iter);
  1522. -	}
  1523. -	db_destroy(channel->users);
  1524. -	if( channel->m ) {
  1525. -		map[channel->m].channel = NULL;
  1526. -		aFree(channel);
  1527. -	} else if ( channel->type == raChSys_ALLY )
  1528. -		aFree(channel);
  1529. -	else if( !raChSys.closing )
  1530. -		strdb_remove(channel_db, channel->name);
  1531. -}
  1532. -
  1533. -void clif_read_channels_config(void) {
  1534. -	config_t channels_conf;
  1535. -	config_setting_t *chsys = NULL;
  1536. -	const char *config_filename = "conf/channels.conf"; // FIXME hardcoded name
  1537. -
  1538. -	if (conf_read_file(&channels_conf, config_filename))
  1539. -		return;
  1540. -
  1541. -	chsys = config_lookup(&channels_conf, "chsys");
  1542. -
  1543. -	if (chsys != NULL) {
  1544. -		config_setting_t *settings = config_setting_get_elem(chsys, 0);
  1545. -		config_setting_t *channels;
  1546. -		config_setting_t *colors;
  1547. -		int i,k;
  1548. -		const char *local_name, *ally_name,
  1549. -					*local_color, *ally_color;
  1550. -		int ally_enabled = 0, local_enabled = 0,
  1551. -			local_autojoin = 0, ally_autojoin = 0,
  1552. -			allow_user_channel_creation = 0;
  1553. -
  1554. -		if( !config_setting_lookup_string(settings, "map_local_channel_name", &local_name) )
  1555. -			local_name = "map";
  1556. -		safestrncpy(raChSys.local_name, local_name, RACHSYS_NAME_LENGTH);
  1557. -
  1558. -		if( !config_setting_lookup_string(settings, "ally_channel_name", &ally_name) )
  1559. -			ally_name = "ally";
  1560. -		safestrncpy(raChSys.ally_name, ally_name, RACHSYS_NAME_LENGTH);
  1561. -
  1562. -		config_setting_lookup_bool(settings, "map_local_channel", &local_enabled);
  1563. -		config_setting_lookup_bool(settings, "ally_channel_enabled", &ally_enabled);
  1564. -
  1565. -		if( local_enabled )
  1566. -			raChSys.local = true;
  1567. -		if( ally_enabled )
  1568. -			raChSys.ally = true;
  1569. -
  1570. -		config_setting_lookup_bool(settings, "map_local_channel_autojoin", &local_autojoin);
  1571. -		config_setting_lookup_bool(settings, "ally_channel_autojoin", &ally_autojoin);
  1572. -
  1573. -		if( local_autojoin )
  1574. -			raChSys.local_autojoin = true;
  1575. -		if( ally_autojoin )
  1576. -			raChSys.ally_autojoin = true;
  1577. -
  1578. -		config_setting_lookup_bool(settings, "allow_user_channel_creation", &allow_user_channel_creation);
  1579. -
  1580. -		if( allow_user_channel_creation )
  1581. -			raChSys.allow_user_channel_creation = true;
  1582. -
  1583. -		if( (colors = config_setting_get_member(settings, "colors")) != NULL ) {
  1584. -			int color_count = config_setting_length(colors);
  1585. -			CREATE( raChSys.colors, unsigned long, color_count );
  1586. -			CREATE( raChSys.colors_name, char *, color_count );
  1587. -			for(i = 0; i < color_count; i++) {
  1588. -				config_setting_t *color = config_setting_get_elem(colors, i);
  1589. -
  1590. -				CREATE( raChSys.colors_name[i], char, RACHSYS_NAME_LENGTH );
  1591. -
  1592. -				safestrncpy(raChSys.colors_name[i], config_setting_name(color), RACHSYS_NAME_LENGTH);
  1593. -
  1594. -				raChSys.colors[i] = strtoul(config_setting_get_string_elem(colors,i),NULL,0);
  1595. -				raChSys.colors[i] = (raChSys.colors[i] & 0x0000FF) << 16 | (raChSys.colors[i] & 0x00FF00) | (raChSys.colors[i] & 0xFF0000) >> 16;//RGB to BGR
  1596. -			}
  1597. -			raChSys.colors_count = color_count;
  1598. -		}
  1599. -
  1600. -		config_setting_lookup_string(settings, "map_local_channel_color", &local_color);
  1601. -
  1602. -		for (k = 0; k < raChSys.colors_count; k++) {
  1603. -			if( strcmpi(raChSys.colors_name[k],local_color) == 0 )
  1604. -				break;
  1605. -		}
  1606. -
  1607. -		if( k < raChSys.colors_count ) {
  1608. -			raChSys.local_color = k;
  1609. -		} else {
  1610. -			ShowError("channels.conf: unknown color '%s' for channel 'map_local_channel_color', disabling '#%s'...\n",local_color,local_name);
  1611. -			raChSys.local = false;
  1612. -		}
  1613. -
  1614. -		config_setting_lookup_string(settings, "ally_channel_color", &ally_color);
  1615. -
  1616. -		for (k = 0; k < raChSys.colors_count; k++) {
  1617. -			if( strcmpi(raChSys.colors_name[k],ally_color) == 0 )
  1618. -				break;
  1619. -		}
  1620. -
  1621. -		if( k < raChSys.colors_count ) {
  1622. -			raChSys.ally_color = k;
  1623. -		} else {
  1624. -			ShowError("channels.conf: unknown color '%s' for channel 'ally_channel_color', disabling '#%s'...\n",local_color,ally_name);
  1625. -			raChSys.ally = false;
  1626. -		}
  1627. -
  1628. -		if( (channels = config_setting_get_member(settings, "default_channels")) != NULL ) {
  1629. -			int channel_count = config_setting_length(channels);
  1630. -
  1631. -			for(i = 0; i < channel_count; i++) {
  1632. -				config_setting_t *channel = config_setting_get_elem(channels, i);
  1633. -				const char *name = config_setting_name(channel);
  1634. -				const char *color = config_setting_get_string_elem(channels,i);
  1635. -				struct raChSysCh *chd;
  1636. -
  1637. -				for (k = 0; k < raChSys.colors_count; k++) {
  1638. -					if( strcmpi(raChSys.colors_name[k],color) == 0 )
  1639. -						break;
  1640. -				}
  1641. -				if( k == raChSys.colors_count ) {
  1642. -					ShowError("channels.conf: unknown color '%s' for channel '%s', skipping channel...\n",color,name);
  1643. -					continue;
  1644. -				}
  1645. -				if( strcmpi(name,raChSys.local_name) == 0 || strcmpi(name,raChSys.ally_name) == 0 || strdb_exists(channel_db, name) ) {
  1646. -					ShowError("channels.conf: duplicate channel '%s', skipping channel...\n",name);
  1647. -					continue;
  1648. -
  1649. -				}
  1650. -				CREATE( chd, struct raChSysCh, 1 );
  1651. -
  1652. -				safestrncpy(chd->name, name, RACHSYS_NAME_LENGTH);
  1653. -				chd->type = raChSys_PUBLIC;
  1654. -
  1655. -				clif_chsys_create(chd,NULL,NULL,k);
  1656. -			}
  1657. -		}
  1658. -
  1659. -		ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' channels in '"CL_WHITE"%s"CL_RESET"'.\n", db_size(channel_db), config_filename);
  1660. -		config_destroy(&channels_conf);
  1661. -	}
  1662. -}
  1663. -
  1664. -
  1665.  /// Displays heal effect (ZC_RECOVERY).
  1666.  /// 013d <var id>.W <amount>.W
  1667.  /// var id:
  1668. @@ -9564,8 +9304,8 @@
  1669.  		status_calc_pc(sd, false); // Some conditions are map-dependent so we must recalculate
  1670.  		sd->state.changemap = false;
  1671.  
  1672. -		if( raChSys.local && raChSys.local_autojoin && !map[sd->bl.m].flag.chsysnolocalaj ) {
  1673. -			clif_chsys_mjoin(sd);
  1674. +		if( Channel_Config.map_enable && Channel_Config.map_autojoin && !map[sd->bl.m].flag.chmautojoin ) {
  1675. +			channel_mjoin(sd);
  1676.  		}
  1677.  	}
  1678.  
  1679. @@ -9867,23 +9607,12 @@
  1680.  	}
  1681.  
  1682.  	if( sd->gcbind ) {
  1683. -		clif_chsys_send(sd->gcbind,sd,message);
  1684. +		channel_send(sd->gcbind,sd,message);
  1685.  		return;
  1686.  	} else if ( sd->fontcolor && !sd->chatID ) {
  1687.  		char mout[200];
  1688. -		unsigned char mylen = 1;
  1689. -
  1690. -		mylen += snprintf(mout, 200, "%s : %s",sd->fakename[0]?sd->fakename:sd->status.name,message);
  1691. -
  1692. -		WFIFOHEAD(fd,mylen + 12);
  1693. -		WFIFOW(fd,0) = 0x2C1;
  1694. -		WFIFOW(fd,2) = mylen + 12;
  1695. -		WFIFOL(fd,4) = sd->bl.id;
  1696. -		WFIFOL(fd,8) = raChSys.colors[sd->fontcolor - 1];
  1697. -		safestrncpy((char*)WFIFOP(fd,12), mout, mylen);
  1698. -		clif_send(WFIFOP(fd,0), WFIFOW(fd,2), &sd->bl, AREA_WOS);
  1699. -		WFIFOL(fd,4) = -sd->bl.id;
  1700. -		WFIFOSET(fd, mylen + 12);
  1701. +		snprintf(mout, 200, "%s : %s",sd->fakename[0]?sd->fakename:sd->status.name,message);
  1702. +		clif_colormes(sd,sd->fontcolor-1,mout);
  1703.  		return;
  1704.  	}
  1705.  
  1706. @@ -10256,29 +9985,28 @@
  1707.  			return;
  1708.  		}
  1709.  	} else if( target[0] == '#' ) {
  1710. -		struct raChSysCh *channel = NULL;
  1711. +		struct Channel *channel = NULL;
  1712.  		char* chname = target;
  1713. +		DBMap* channel_db = channel_get_db();
  1714.  
  1715.  		chname++;
  1716.  
  1717. -		if( raChSys.local && strcmpi(chname, raChSys.local_name) == 0 ) {
  1718. -			if( !map[sd->bl.m].channel ) {
  1719. -				clif_chsys_mjoin(sd);
  1720. -			}
  1721. +		if( Channel_Config.map_enable && strcmpi(chname, Channel_Config.map_chname) == 0 ) {
  1722. +			if( !map[sd->bl.m].channel ) channel_mjoin(sd);
  1723.  			channel = map[sd->bl.m].channel;
  1724. -		} else if( raChSys.ally && sd->status.guild_id && strcmpi(chname, raChSys.ally_name) == 0 ) {
  1725. +		} else if( Channel_Config.ally_enable && sd->status.guild_id && strcmpi(chname, Channel_Config.ally_chname) == 0 ) {
  1726.  			struct guild *g = sd->guild;
  1727.  			if( !g ) return;
  1728. -			channel = (struct raChSysCh *)g->channel;
  1729. +			channel = (struct Channel *)g->channel;
  1730.  		}
  1731.  		if( channel || (channel = strdb_get(channel_db,chname)) ) {
  1732.  			unsigned char k;
  1733.  			ARR_FIND(0, sd->channel_count, k, sd->channels[k] == channel);
  1734. -			if( k < sd->channel_count ) {
  1735. -				clif_chsys_send(channel,sd,message);
  1736. -			} else if( channel->pass[0] == '\0' ) {
  1737. -				clif_chsys_join(channel,sd);
  1738. -				clif_chsys_send(channel,sd,message);
  1739. +			if( k < sd->channel_count ) { //in there
  1740. +				channel_send(channel,sd,message);
  1741. +			} else if( channel->pass[0] == '\0' ) { //no pass needed
  1742. +				channel_join(channel,sd);
  1743. +				channel_send(channel,sd,message);
  1744.  			} else {
  1745.  				clif_displaymessage(fd, msg_txt(sd,1402)); //You're not in that channel, type '@join <#channel_name>'
  1746.  			}
  1747. @@ -17374,34 +17102,9 @@
  1748.  	add_timer_func_list(clif_delayquit, "clif_delayquit");
  1749.  
  1750.  	delay_clearunit_ers = ers_new(sizeof(struct block_list),"clif.c::delay_clearunit_ers",ERS_OPT_CLEAR);
  1751. -
  1752. -	channel_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, RACHSYS_NAME_LENGTH);
  1753. -	raChSys.ally = raChSys.local = raChSys.ally_autojoin = raChSys.local_autojoin = false;
  1754. -	clif_read_channels_config();
  1755. -
  1756.  	return 0;
  1757.  }
  1758.  
  1759.  void do_final_clif(void) {
  1760. -	DBIterator *iter = db_iterator(channel_db);
  1761. -	struct raChSysCh *channel;
  1762. -	unsigned char i;
  1763. -
  1764. -	for( channel = dbi_first(iter); dbi_exists(iter); channel = dbi_next(iter) ) {
  1765. -		clif_chsys_delete(channel);
  1766. -	}
  1767. -
  1768. -	dbi_destroy(iter);
  1769. -
  1770. -	for(i = 0; i < raChSys.colors_count; i++) {
  1771. -		aFree(raChSys.colors_name[i]);
  1772. -	}
  1773. -
  1774. -	if( raChSys.colors_count ) {
  1775. -		aFree(raChSys.colors_name);
  1776. -		aFree(raChSys.colors);
  1777. -	}
  1778. -
  1779. -	db_destroy(channel_db);
  1780.  	ers_destroy(delay_clearunit_ers);
  1781.  }
  1782. Index: src/map/clif.h
  1783. ===================================================================
  1784. --- src/map/clif.h	(revision 17267)
  1785. +++ src/map/clif.h	(working copy)
  1786. @@ -6,7 +6,9 @@
  1787.  
  1788.  #include "../common/cbasetypes.h"
  1789.  #include "../common/db.h" //dbmap
  1790. +
  1791.  //#include "../common/mmo.h"
  1792. +struct Channel;
  1793.  struct item;
  1794.  struct storage_data;
  1795.  struct guild_storage;
  1796. @@ -775,56 +777,8 @@
  1797.  unsigned long color_table[COLOR_MAX];
  1798.  int clif_colormes(struct map_session_data * sd, enum clif_colors color, const char* msg);
  1799.  
  1800. -/**
  1801. - * Channel System
  1802. - **/
  1803. -#define RACHSYS_NAME_LENGTH 20
  1804. +void clif_channel_msg(struct Channel *channel, struct map_session_data *sd, char *msg);
  1805.  
  1806. -enum raChSysChOpt {
  1807. -	raChSys_OPT_BASE				= 0,
  1808. -	raChSys_OPT_ANNOUNCE_JOIN	= 1,
  1809. -};
  1810. -
  1811. -enum raChSysChType {
  1812. -	raChSys_PUBLIC	= 0,
  1813. -	raChSys_PRIVATE	= 1,
  1814. -	raChSys_MAP		= 2,
  1815. -	raChSys_ALLY		= 3,
  1816. -};
  1817. -
  1818. -struct {
  1819. -	unsigned long *colors;
  1820. -	char **colors_name;
  1821. -	unsigned char colors_count;
  1822. -	bool local, ally;
  1823. -	bool local_autojoin, ally_autojoin;
  1824. -	char local_name[RACHSYS_NAME_LENGTH], ally_name[RACHSYS_NAME_LENGTH];
  1825. -	unsigned char local_color, ally_color;
  1826. -	bool closing;
  1827. -	bool allow_user_channel_creation;
  1828. -} raChSys;
  1829. -
  1830. -struct raChSysCh {
  1831. -	char name[RACHSYS_NAME_LENGTH];
  1832. -	char pass[RACHSYS_NAME_LENGTH];
  1833. -	unsigned char color;
  1834. -	DBMap *users;
  1835. -	unsigned int opt;
  1836. -	unsigned int owner;
  1837. -	enum raChSysChType type;
  1838. -	uint16 m;
  1839. -};
  1840. -
  1841. -struct DBMap* clif_get_channel_db(void);
  1842. -void clif_chsys_create(struct raChSysCh *channel, char *name, char *pass, unsigned char color);
  1843. -void clif_chsys_msg(struct raChSysCh *channel, struct map_session_data *sd, char *msg);
  1844. -void clif_chsys_send(struct raChSysCh *channel, struct map_session_data *sd, char *msg);
  1845. -void clif_chsys_join(struct raChSysCh *channel, struct map_session_data *sd);
  1846. -void clif_chsys_left(struct raChSysCh *channel, struct map_session_data *sd);
  1847. -void clif_chsys_delete(struct raChSysCh *channel);
  1848. -void clif_chsys_mjoin(struct map_session_data *sd);
  1849. -void clif_read_channels_config(void);
  1850. -
  1851.  #define clif_menuskill_clear(sd) (sd)->menuskill_id = (sd)->menuskill_val = (sd)->menuskill_val2 = 0;
  1852.  
  1853.  #endif /* _CLIF_H_ */
  1854. Index: src/map/guild.c
  1855. ===================================================================
  1856. --- src/map/guild.c	(revision 17267)
  1857. +++ src/map/guild.c	(working copy)
  1858. @@ -21,6 +21,7 @@
  1859.  #include "mob.h"
  1860.  #include "intif.h"
  1861.  #include "clif.h"
  1862. +#include "channel.h"
  1863.  #include "skill.h"
  1864.  #include "log.h"
  1865.  
  1866. @@ -499,7 +500,6 @@
  1867.  	DBData data;
  1868.  	struct map_session_data *sd;
  1869.  	bool guild_new = false;
  1870. -	void *aChSysSave = NULL;
  1871.  
  1872.  	nullpo_ret(sg);
  1873.  
  1874. @@ -507,40 +507,6 @@
  1875.  		guild_new = true;
  1876.  		g=(struct guild *)aCalloc(1,sizeof(struct guild));
  1877.  		idb_put(guild_db,sg->guild_id,g);
  1878. -		if( raChSys.ally ) {
  1879. -			struct raChSysCh *channel;
  1880. -
  1881. -			CREATE(channel, struct raChSysCh , 1);
  1882. -			safestrncpy(channel->name, raChSys.ally_name, RACHSYS_NAME_LENGTH);
  1883. -			channel->type = raChSys_ALLY;
  1884. -
  1885. -			clif_chsys_create(channel,NULL,NULL,raChSys.ally_color);
  1886. -			if( raChSys.ally_autojoin ) {
  1887. -				struct s_mapiterator* iter = mapit_getallusers();
  1888. -
  1889. -				for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) ) {
  1890. -					if( sd->status.guild_id ) {
  1891. -						if( sd->status.guild_id == sg->guild_id ) {
  1892. -							clif_chsys_join(channel,sd);
  1893. -							sd->guild = g;
  1894. -							continue;
  1895. -						}
  1896. -
  1897. -						for (i = 0; i < MAX_GUILDALLIANCE; i++) {
  1898. -							if( sg->alliance[i].guild_id == sd->status.guild_id ) {
  1899. -								clif_chsys_join(channel,sd);
  1900. -								break;
  1901. -							}
  1902. -						}
  1903. -					}
  1904. -				}
  1905. -
  1906. -				mapit_free(iter);
  1907. -			}
  1908. -
  1909. -			aChSysSave = (void*)channel;
  1910. -
  1911. -		}
  1912.  		before=*sg;
  1913.  		//Perform the check on the user because the first load
  1914.  		guild_check_member(sg);
  1915. @@ -558,13 +524,9 @@
  1916.  		}
  1917.  	} else {
  1918.  		before=*g;
  1919. -		if( g->channel )
  1920. -			aChSysSave = g->channel;
  1921.  	}
  1922.  	memcpy(g,sg,sizeof(struct guild));
  1923.  
  1924. -	g->channel = aChSysSave;
  1925. -
  1926.  	if(g->max_member > MAX_GUILD) {
  1927.  		ShowError("guild_recv_info: Received guild with %d members, but MAX_GUILD is only %d. Extra guild-members have been lost!\n", g->max_member, MAX_GUILD);
  1928.  		g->max_member = MAX_GUILD;
  1929. @@ -586,6 +548,9 @@
  1930.  		if( sd==NULL )
  1931.  			continue;
  1932.  		sd->guild = g;
  1933. +		if( Channel_Config.ally_enable && Channel_Config.ally_autojoin ) {
  1934. +			channel_gjoin(sd,3);
  1935. +		}
  1936.  
  1937.  		if (before.guild_lv != g->guild_lv || bm != m ||
  1938.  			before.max_member != g->max_member) {
  1939. @@ -607,6 +572,8 @@
  1940.  		}
  1941.  	}
  1942.  
  1943. +
  1944. +
  1945.  	//Occurrence of an event
  1946.  	if (guild_infoevent_db->remove(guild_infoevent_db, db_i2key(sg->guild_id), &data)) {
  1947.  		struct eventlist *ev = db_data2ptr(&data), *ev2;
  1948. @@ -755,16 +722,8 @@
  1949.  		g->member[i].sd = sd;
  1950.  		sd->guild = g;
  1951.  
  1952. -		if( raChSys.ally && raChSys.ally_autojoin ) {
  1953. -			struct guild* sg = NULL;
  1954. -			clif_chsys_join((struct raChSysCh*)g->channel,sd);
  1955. -
  1956. -			for (i = 0; i < MAX_GUILDALLIANCE; i++) {
  1957. -				if( g->alliance[i].guild_id && (sg = guild_search(g->alliance[i].guild_id) ) ) {
  1958. -					clif_chsys_join((struct raChSysCh*)sg->channel,sd);
  1959. -					break;
  1960. -				}
  1961. -			}
  1962. +		if( Channel_Config.ally_enable && Channel_Config.ally_autojoin ) {
  1963. +			channel_gjoin(sd,3);
  1964.  		}
  1965.  	}
  1966.  }
  1967. @@ -909,13 +868,7 @@
  1968.  		if (sd->state.storage_flag == 2) //Close the guild storage.
  1969.  			storage_guild_storageclose(sd);
  1970.  		guild_send_dot_remove(sd);
  1971. -		if( raChSys.ally ) {
  1972. -			uint8 ch_count = sd->channel_count;
  1973. -			for (i = 0; i < ch_count; i++) {
  1974. -				if( sd->channels[i] && sd->channels[i]->type == raChSys_ALLY )
  1975. -					clif_chsys_left(sd->channels[i],sd);
  1976. -			}
  1977. -		}
  1978. +		channel_pcquit(sd,1); //leave guild and ally chan
  1979.  		sd->status.guild_id = 0;
  1980.  		sd->guild = NULL;
  1981.  		sd->guild_emblem_id = 0;
  1982. @@ -1624,14 +1577,14 @@
  1983.  		sd[0]->guild_alliance_account=0;
  1984.  	}
  1985.  
  1986. -    if (flag & 0x70) { // failure
  1987. +	if (flag & 0x70) { // failure
  1988.  		for(i=0;i<2-(flag&1);i++)
  1989.  			if( sd[i]!=NULL )
  1990.  				clif_guild_allianceack(sd[i],((flag>>4)==i+1)?3:4);
  1991.  		return 0;
  1992.  	}
  1993.  
  1994. -    if (!(flag & 0x08)) { // new relationship
  1995. +	if (!(flag & 0x08)) { // new relationship
  1996.  		for(i=0;i<2-(flag&1);i++)
  1997.  		{
  1998.  			if(g[i]!=NULL)
  1999. @@ -1645,7 +1598,7 @@
  2000.  				}
  2001.  			}
  2002.  		}
  2003. -    } else { // remove relationship
  2004. +	} else { // remove relationship
  2005.  		for(i=0;i<2-(flag&1);i++)
  2006.  		{
  2007.  			if(g[i]!=NULL)
  2008. @@ -1654,26 +1607,28 @@
  2009.  				if( j < MAX_GUILDALLIANCE )
  2010.  					g[i]->alliance[j].guild_id = 0;
  2011.  			}
  2012. -            if (sd[i] != NULL) // notify players
  2013. +		if (sd[i] != NULL) // notify players
  2014.  				clif_guild_delalliance(sd[i],guild_id[1-i],(flag&1));
  2015.  		}
  2016.  	}
  2017.  
  2018. -    if ((flag & 0x0f) == 0) { // alliance notification
  2019. +	if ((flag & 0x0f) == 0) { // alliance notification
  2020.  		if( sd[1]!=NULL )
  2021.  			clif_guild_allianceack(sd[1],2);
  2022. -    } else if ((flag & 0x0f) == 1) { // enemy notification
  2023. +	} else if ((flag & 0x0f) == 1) { // enemy notification
  2024.  		if( sd[0]!=NULL )
  2025.  			clif_guild_oppositionack(sd[0],0);
  2026.  	}
  2027.  
  2028.  
  2029. -    for (i = 0; i < 2 - (flag & 1); i++) { // Retransmission of the relationship list to all members
  2030. +	for (i = 0; i < 2 - (flag & 1); i++) { // Retransmission of the relationship list to all members
  2031.  		struct map_session_data *sd;
  2032.  		if(g[i]!=NULL)
  2033.  			for(j=0;j<g[i]->max_member;j++)
  2034. -				if((sd=g[i]->member[j].sd)!=NULL)
  2035. +				if((sd=g[i]->member[j].sd)!=NULL){
  2036.  					clif_guild_allianceinfo(sd);
  2037. +					channel_gjoin(sd,2);
  2038. +				}
  2039.  	}
  2040.  	return 0;
  2041.  }
  2042. @@ -1751,10 +1706,8 @@
  2043.  	guild_db->foreach(guild_db,guild_broken_sub,guild_id);
  2044.  	castle_db->foreach(castle_db,castle_guild_broken_sub,guild_id);
  2045.  	guild_storage_delete(guild_id);
  2046. -	if( raChSys.ally ) {
  2047. -		if( g->channel != NULL ) {
  2048. -			clif_chsys_delete(( struct raChSysCh * )g->channel);
  2049. -		}
  2050. +	if( Channel_Config.ally_enable ) {
  2051. +		channel_delete(( struct Channel * )g->channel);
  2052.  	}
  2053.  	idb_remove(guild_db,guild_id);
  2054.  	return 0;
  2055. @@ -2203,8 +2156,7 @@
  2056.  	struct guild *g;
  2057.  
  2058.  	for( g = dbi_first(iter); dbi_exists(iter); g = dbi_next(iter) ) {
  2059. -		if( g->channel != NULL )
  2060. -			clif_chsys_delete((struct raChSysCh *)g->channel);
  2061. +		channel_delete((struct Channel *)g->channel);
  2062.  	}
  2063.  
  2064.  	dbi_destroy(iter);
Viewed 592 times, submitted by lighta.