Index: conf/msg_conf/map_msg.conf
===================================================================
--- conf/msg_conf/map_msg.conf (revision 17267)
+++ conf/msg_conf/map_msg.conf (working copy)
@@ -1457,6 +1457,7 @@
1433: Your global chat is now unbinded from the '#%s' channel.
1434: You're already in the '%s' channel.
1435: You're now in the '#%s' channel for '%s'.
+1436: Channel pass can't be higher then %d.
//Custom translations
//import: conf/msg_conf/import/map_msg_eng_conf.txt
Index: src/map/npc.c
===================================================================
--- src/map/npc.c (revision 17267)
+++ src/map/npc.c (working copy)
@@ -2138,7 +2138,7 @@
return strchr(start,'\n');// skip and continue
}
- if( m != -1 && ( x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) ) {
+ if( m != -1 && ( x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) ) {
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));
}
@@ -2209,7 +2209,7 @@
if( m != -1 && ( x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) ) {
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));
- }
+ }
if( !strcasecmp(w2,"cashshop") )
type = CASHSHOP;
@@ -3429,7 +3429,7 @@
else if (!strcmpi(w3,"reset"))
map[m].flag.reset=state;
else if (!strcmpi(w3,"nomapchannelautojoin"))
- map[m].flag.chsysnolocalaj = state;
+ map[m].flag.chmautojoin = state;
else
ShowError("npc_parse_mapflag: unrecognized mapflag '%s' (file '%s', line '%d').\n", w3, filepath, strline(buffer,start-buffer));
Index: src/map/status.c
===================================================================
--- src/map/status.c (revision 17267)
+++ src/map/status.c (working copy)
@@ -10091,7 +10091,7 @@
int hp = rnd()%600 + 200;
struct block_list* src = map_id2bl(sce->val2);
if( src && bl && bl->type == BL_MOB ){
- mob_log_damage( (TBL_MOB*)bl, src, sd || hp < status->hp ? hp : status->hp - 1 );
+ mob_log_damage( (TBL_MOB*)bl, src, sd || hp < status->hp ? hp : status->hp - 1 );
}
map_freeblock_lock();
status_fix_damage(src, bl, sd||hp<status->hp?hp:status->hp-1, 1);
Index: src/map/pc.c
===================================================================
--- src/map/pc.c (revision 17267)
+++ src/map/pc.c (working copy)
@@ -16,6 +16,7 @@
#include "atcommand.h" // get_atcommand_level()
#include "battle.h" // battle_config
#include "battleground.h"
+#include "channel.h"
#include "chrif.h"
#include "clif.h"
#include "date.h" // is_day_of_*()
@@ -1249,7 +1250,7 @@
}
clif_changeoption( &sd->bl );
- }
+ }
return 1;
}
@@ -4782,9 +4783,7 @@
vending_closevending(sd);
}
- if( raChSys.local && map[sd->bl.m].channel && idb_exists(map[sd->bl.m].channel->users, sd->status.char_id) ) {
- clif_chsys_left(map[sd->bl.m].channel,sd);
- }
+ channel_pcquit(sd,4); //quit map chan
}
if( m < 0 )
@@ -9604,7 +9603,7 @@
FILE *fp;
char line[24000],*p;
- //reset
+ //reset
memset(exp_table,0,sizeof(exp_table));
memset(max_level,0,sizeof(max_level));
@@ -9651,7 +9650,7 @@
//Reverse check in case the array has a bunch of trailing zeros... [Skotlex]
//The reasoning behind the -2 is this... if the max level is 5, then the array
//should look like this:
- //0: x, 1: x, 2: x: 3: x 4: 0 <- last valid value is at 3.
+ //0: x, 1: x, 2: x: 3: x 4: 0 <- last valid value is at 3.
while ((ui = max_level[job][type]) >= 2 && exp_table[job][type][ui-2] <= 0)
max_level[job][type]--;
if (max_level[job][type] < maxlv) {
@@ -9762,7 +9761,7 @@
fclose(fp);
ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","attr_fix.txt");
- // reset then read statspoint
+ // reset then read statspoint
memset(statp,0,sizeof(statp));
i=1;
Index: src/map/pc.h
===================================================================
--- src/map/pc.h (revision 17267)
+++ src/map/pc.h (working copy)
@@ -499,9 +499,9 @@
int shadowform_id;
/* Channel System [Ind] */
- struct raChSysCh **channels;
+ struct Channel **channels;
unsigned char channel_count;
- struct raChSysCh *gcbind;
+ struct Channel *gcbind;
bool stealth;
unsigned char fontcolor; /* debug-only */
Index: src/map/map.c
===================================================================
--- src/map/map.c (revision 17267)
+++ src/map/map.c (working copy)
@@ -48,6 +48,8 @@
#include "log.h"
#include "mail.h"
#include "cashshop.h"
+#include "channel.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -3546,7 +3548,7 @@
struct s_mapiterator* iter;
ShowStatus("Terminating...\n");
- raChSys.closing = true;
+ Channel_Config.closing = true;
//Ladies and babies first.
iter = mapit_getallusers();
@@ -3562,8 +3564,7 @@
ShowStatus("Cleaning up maps [%d/%d]: %s..."CL_CLL"\r", i+1, map_num, map[i].name);
if (map[i].m >= 0) {
map_foreachinmap(cleanup_sub, i, BL_ALL);
- if( map[i].channel != NULL )
- clif_chsys_delete((struct raChSysCh *)map[i].channel);
+ channel_delete((struct Channel *)map[i].channel);
}
}
ShowStatus("Cleaned up %d maps."CL_CLL"\n", map_num);
@@ -3574,6 +3575,7 @@
do_final_atcommand();
do_final_battle();
+ do_final_channel();
do_final_chrif();
do_final_clif();
do_final_npc();
@@ -3876,6 +3878,7 @@
do_init_atcommand();
do_init_battle();
do_init_instance();
+ do_init_channel();
do_init_chrif();
do_init_clif();
do_init_script();
Index: src/map/map.h
===================================================================
--- src/map/map.h (revision 17267)
+++ src/map/map.h (working copy)
@@ -17,7 +17,7 @@
struct npc_data;
struct item_data;
-struct raChSysCh;
+struct Channel;
enum E_MAPSERVER_ST {
MAPSERVER_ST_RUNNING = CORE_ST_LAST,
@@ -567,7 +567,7 @@
unsigned guildlock :1;
unsigned src4instance : 1; // To flag this map when it's used as a src map for instances
unsigned reset :1; // [Daegaladh]
- unsigned chsysnolocalaj : 1;
+ unsigned chmautojoin : 1; //prevent to auto join map channel
} flag;
struct point save;
struct npc_data *npc[MAX_NPC_PER_MAP];
@@ -595,7 +595,7 @@
int instance_src_map;
/* rAthena Local Chat */
- struct raChSysCh *channel;
+ struct Channel *channel;
};
/// Stores information about a remote map (for multi-mapserver setups).
Index: src/map/Makefile.in
===================================================================
--- src/map/Makefile.in (revision 17267)
+++ src/map/Makefile.in (working copy)
@@ -17,7 +17,7 @@
storage.o skill.o atcommand.o battle.o battleground.o \
intif.o trade.o party.o vending.o guild.o pet.o \
log.o mail.o date.o unit.o homunculus.o mercenary.o quest.o instance.o \
- buyingstore.o searchstore.o duel.o pc_groups.o elemental.o cashshop.o
+ buyingstore.o searchstore.o duel.o pc_groups.o elemental.o cashshop.o channel.o
MAP_SQL_OBJ = $(MAP_OBJ:%=obj_sql/%) \
obj_sql/mapreg_sql.o
MAP_H = map.h chrif.h clif.h pc.h status.h npc.h \
@@ -25,7 +25,7 @@
storage.h skill.h atcommand.h battle.h battleground.h \
intif.h trade.h party.h vending.h guild.h pet.h \
log.h mail.h date.h unit.h homunculus.h mercenary.h quest.h instance.h mapreg.h \
- buyingstore.h searchstore.h duel.h pc_groups.h elemental.h cashshop.h \
+ buyingstore.h searchstore.h duel.h pc_groups.h elemental.h cashshop.h channel.h\
../config/core.h ../config/renewal.h ../config/secure.h ../config/const.h \
../config/classes/general.h
@@ -91,10 +91,10 @@
# missing object files
../common/obj_all/common.a:
@$(MAKE) -C ../common sql
-
+
../common/obj_sql/common_sql.a:
@$(MAKE) -C ../common sql
-
+
MT19937AR_OBJ:
@$(MAKE) -C ../../3rdparty/mt19937ar
Index: src/map/atcommand.c
===================================================================
--- src/map/atcommand.c (revision 17267)
+++ src/map/atcommand.c (working copy)
@@ -17,6 +17,7 @@
#include "atcommand.h"
#include "battle.h"
#include "chat.h"
+#include "channel.h"
#include "clif.h"
#include "chrif.h"
#include "duel.h"
@@ -5621,28 +5622,7 @@
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);
}
- // Leave all chat channels.
- if( raChSys.ally && sd->status.guild_id ) {
- struct guild *g = sd->guild, *sg;
- if( g ) {
- if( idb_exists(((struct raChSysCh *)g->channel)->users, sd->status.char_id) )
- clif_chsys_left((struct raChSysCh *)g->channel,sd);
- for (i = 0; i < MAX_GUILDALLIANCE; i++) {
- if( g->alliance[i].guild_id && (sg = guild_search(g->alliance[i].guild_id) ) ) {
- if( idb_exists(((struct raChSysCh *)sg->channel)->users, sd->status.char_id) )
- clif_chsys_left((struct raChSysCh *)sg->channel,sd);
- break;
- }
- }
- }
- }
- if( sd->channel_count ) { //quit all chan
- uint8 count = sd->channel_count;
- for( i = 0; i < count; i++ ) {
- if( sd->channels[i] != NULL )
- clif_chsys_left(sd->channels[i],sd);
- }
- }
+ channel_pcquit(sd,7); //leave all chan
clif_authfail_fd(sd->fd, 15);
return 0;
@@ -8784,25 +8764,25 @@
/* Channel System [Ind] */
ACMD_FUNC(join)
{
- struct raChSysCh *channel;
- char name[RACHSYS_NAME_LENGTH], pass[RACHSYS_NAME_LENGTH];
- DBMap* channel_db = clif_get_channel_db();
+ struct Channel *channel;
+ char name[CHAN_NAME_LENGTH], pass[CHAN_NAME_LENGTH];
+ DBMap* channel_db = channel_get_db();
if( !message || !*message || sscanf(message, "%s %s", name, pass) < 1 ) {
sprintf(atcmd_output, msg_txt(sd,1399),command); // Unknown Channel (usage: %s <#channel_name>)
clif_displaymessage(fd, atcmd_output);
return -1;
}
- if( raChSys.local && strcmpi(name + 1, raChSys.local_name) == 0 ) {
+ if( Channel_Config.map_enable && strcmpi(name + 1, Channel_Config.map_chname) == 0 ) {
if( !map[sd->bl.m].channel ) {
- clif_chsys_mjoin(sd);
+ channel_mjoin(sd);
return 0;
} else
channel = map[sd->bl.m].channel;
- } else if( raChSys.ally && sd->status.guild_id && strcmpi(name + 1, raChSys.ally_name) == 0 ) {
+ } else if( Channel_Config.ally_enable && sd->status.guild_id && strcmpi(name + 1, Channel_Config.ally_chname) == 0 ) {
struct guild *g = sd->guild;
if( !g ) return -1;/* unlikely, but we wont let it crash anyway. */
- channel = (struct raChSysCh *)g->channel;
+ channel = (struct Channel *)g->channel;
} else if( !( channel = strdb_get(channel_db, name + 1) ) ) {
sprintf(atcmd_output, msg_txt(sd,1400),name,command); // Unknown Channel '%s' (usage: %s <#channel_name>)
clif_displaymessage(fd, atcmd_output);
@@ -8824,12 +8804,12 @@
}
}
- if( !( channel->opt & raChSys_OPT_ANNOUNCE_JOIN ) ) {
+ if( !( channel->opt & CHAN_OPT_ANNOUNCE_JOIN ) ) {
sprintf(atcmd_output, msg_txt(sd,1403),name); // You're now in the '%s' channel.
clif_displaymessage(fd, atcmd_output);
}
- clif_chsys_join(channel,sd);
+ channel_join(channel,sd);
return 0;
}
@@ -8869,164 +8849,31 @@
ACMD_FUNC(channel)
{
- struct raChSysCh *channel;
- char key[RACHSYS_NAME_LENGTH], sub1[RACHSYS_NAME_LENGTH], sub2[RACHSYS_NAME_LENGTH], sub3[RACHSYS_NAME_LENGTH];
+ struct Channel *channel;
+ char key[CHAN_NAME_LENGTH], sub1[CHAN_NAME_LENGTH], sub2[CHAN_NAME_LENGTH], sub3[CHAN_NAME_LENGTH];
unsigned char k = 0;
- DBMap* channel_db = clif_get_channel_db();
+ DBMap* channel_db = channel_get_db();
sub1[0] = sub2[0] = sub3[0] = '\0';
if( !message || !*message || sscanf(message, "%s %s %s %s", key, sub1, sub2, sub3) < 1 ) {
- atcmd_channel_help(sd,command,( raChSys.allow_user_channel_creation || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ));
+ atcmd_channel_help(sd,command,( Channel_Config.user_chenable || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ));
return 0;
}
- if( strcmpi(key,"create") == 0 && ( raChSys.allow_user_channel_creation || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ) ) {
- if( sub1[0] != '#' ) {
- clif_displaymessage(fd, msg_txt(sd,1405));// Channel name must start with '#'.
- return -1;
- } else if ( strlen(sub1) < 3 || strlen(sub1) > RACHSYS_NAME_LENGTH ) {
- sprintf(atcmd_output, msg_txt(sd,1406), RACHSYS_NAME_LENGTH);// Channel length must be between 3 and %d.
- clif_displaymessage(fd, atcmd_output);
- return -1;
- } else if ( sub3[0] != '\0' ) {
- clif_displaymessage(fd, msg_txt(sd,1408)); // Channel password may not contain spaces.
- return -1;
- }
- if( strcmpi(sub1 + 1,raChSys.local_name) == 0 || strcmpi(sub1 + 1,raChSys.ally_name) == 0 || strdb_exists(channel_db, sub1 + 1) ) {
- sprintf(atcmd_output, msg_txt(sd,1407), sub1);// Channel '%s' is not available.
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
-
- CREATE( channel, struct raChSysCh, 1 );
-
- clif_chsys_create(channel,sub1 + 1,sub2,0);
-
- channel->owner = sd->status.char_id;
- channel->type = raChSys_PRIVATE;
-
- if( !( channel->opt & raChSys_OPT_ANNOUNCE_JOIN ) ) {
- sprintf(atcmd_output, msg_txt(sd,1403),sub1); // You're now in the '%s' channel.
- clif_displaymessage(fd, atcmd_output);
- }
-
- clif_chsys_join(channel,sd);
-
+ if( strcmpi(key,"create") == 0 && ( Channel_Config.user_chenable || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ) ) {
+ return channel_pccreate(sd,sub1,sub2);
} else if ( strcmpi(key,"list") == 0 ) {
- if( sub1[0] != '\0' && strcmpi(sub1,"colors") == 0 ) {
- char mout[40];
- for( k = 0; k < raChSys.colors_count; k++ ) {
- unsigned short msg_len = 1;
- msg_len += sprintf(mout, "[ %s list colors ] : %s",command,raChSys.colors_name[k]);
-
- WFIFOHEAD(fd,msg_len + 12);
- WFIFOW(fd,0) = 0x2C1;
- WFIFOW(fd,2) = msg_len + 12;
- WFIFOL(fd,4) = 0;
- WFIFOL(fd,8) = raChSys.colors[k];
- safestrncpy((char*)WFIFOP(fd,12), mout, msg_len);
- WFIFOSET(fd, msg_len + 12);
- }
- } else {
- DBIterator *iter;
- bool show_all = pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ? true : false;
- clif_displaymessage(fd, msg_txt(sd,1410)); // ---- Public Channels ----
- if( raChSys.local ) {
- 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 )
- clif_displaymessage(fd, atcmd_output);
- }
- if( raChSys.ally && sd->status.guild_id ) {
- struct guild *g = sd->guild;
- if( !g ) return -1;
- sprintf(atcmd_output, msg_txt(sd,1409), raChSys.ally_name, db_size(((struct raChSysCh *)g->channel)->users));// - #%s ( %d users )
- clif_displaymessage(fd, atcmd_output);
- }
- iter = db_iterator(channel_db);
- for(channel = dbi_first(iter); dbi_exists(iter); channel = dbi_next(iter)) {
- if( show_all || channel->type == raChSys_PUBLIC ) {
- sprintf(atcmd_output, msg_txt(sd,1409), channel->name, db_size(channel->users));// - #%s (%d users)
- clif_displaymessage(fd, atcmd_output);
- }
- }
- dbi_destroy(iter);
- }
+ return channel_display_list(sd,sub1);
} else if ( strcmpi(key,"setcolor") == 0 ) {
-
- if( sub1[0] != '#' ) {
- clif_displaymessage(fd, msg_txt(sd,1405));// Channel name must start with '#'.
- return -1;
- }
-
- if( !(channel = strdb_get(channel_db, sub1 + 1)) ) {
- sprintf(atcmd_output, msg_txt(sd,1407), sub1);// Channel '%s' is not available.
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
-
- if( channel->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ) {
- sprintf(atcmd_output, msg_txt(sd,1412), sub1);// You're not the owner of channel '%s'.
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
-
- for( k = 0; k < raChSys.colors_count; k++ ) {
- if( strcmpi(sub2,raChSys.colors_name[k]) == 0 )
- break;
- }
- if( k == raChSys.colors_count ) {
- sprintf(atcmd_output, msg_txt(sd,1411), sub2);// Unknown color '%s'.
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
- channel->color = k;
- sprintf(atcmd_output, msg_txt(sd,1413),sub1,raChSys.colors_name[k]);// '%s' channel color updated to '%s'.
- clif_displaymessage(fd, atcmd_output);
+ return channel_pccolor(sd, sub1, sub2);
} else if ( strcmpi(key,"leave") == 0 ) {
-
- if( sub1[0] != '#' ) {
- clif_displaymessage(fd, msg_txt(sd,1405));// Channel name must start with '#'.
- return -1;
- }
-
- ARR_FIND(0, sd->channel_count, k, strcmpi(sub1+1,sd->channels[k]->name) == 0);
- if( k == sd->channel_count ) {
- sprintf(atcmd_output, msg_txt(sd,1425),sub1);// You're not part of the '%s' channel.
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
- clif_chsys_left(sd->channels[k],sd);
- sprintf(atcmd_output, msg_txt(sd,1426),sub1); // You've left the '%s' channel.
- clif_displaymessage(fd, atcmd_output);
+ return channel_leave(sd, sub1);
} else if ( strcmpi(key,"bindto") == 0 ) {
-
- if( sub1[0] != '#' ) {
- clif_displaymessage(fd, msg_txt(sd,1405));// Channel name must start with '#'.
- return -1;
- }
-
- ARR_FIND(0, sd->channel_count, k, strcmpi(sub1+1,sd->channels[k]->name) == 0);
- if( k == sd->channel_count ) {
- sprintf(atcmd_output, msg_txt(sd,1425),sub1);// You're not part of the '%s' channel.
- clif_displaymessage(fd, atcmd_output);
- return -1;
- }
-
- sd->gcbind = sd->channels[k];
- sprintf(atcmd_output, msg_txt(sd,1431),sub1); // Your global chat is now binded to the '%s' channel.
- clif_displaymessage(fd, atcmd_output);
+ return channel_pcbind(sd, sub1);
} else if ( strcmpi(key,"unbind") == 0 ) {
-
- if( sd->gcbind == NULL ) {
- clif_displaymessage(fd, msg_txt(sd,1432));// Your global chat is not binded to any channel.
- return -1;
- }
-
- sprintf(atcmd_output, msg_txt(sd,1433),sd->gcbind->name); // Your global chat is now unbinded from the '#%s' channel.
- clif_displaymessage(fd, atcmd_output);
-
- sd->gcbind = NULL;
+ return channel_pcunbind(sd);
} else {
- atcmd_channel_help(sd,command,( raChSys.allow_user_channel_creation || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ));
+ atcmd_channel_help(sd,command,( Channel_Config.user_chenable || pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ));
}
return 0;
@@ -9038,17 +8885,9 @@
if( !message || !*message ) {
char mout[40];
- for( k = 0; k < raChSys.colors_count; k++ ) {
- unsigned short msg_len = 1;
- msg_len += sprintf(mout, "[ %s ] : %s",command,raChSys.colors_name[k]);
-
- WFIFOHEAD(fd,msg_len + 12);
- WFIFOW(fd,0) = 0x2C1;
- WFIFOW(fd,2) = msg_len + 12;
- WFIFOL(fd,4) = 0;
- WFIFOL(fd,8) = raChSys.colors[k];
- safestrncpy((char*)WFIFOP(fd,12), mout, msg_len);
- WFIFOSET(fd, msg_len + 12);
+ for( k = 0; k < Channel_Config.colors_count; k++ ) {
+ sprintf(mout, "[ %s ] : %s",command,Channel_Config.colors_name[k]);
+ clif_colormes(sd,k,mout);
}
return -1;
}
@@ -9059,11 +8898,8 @@
return 0;
}
- for( k = 0; k < raChSys.colors_count; k++ ) {
- if( strcmpi(message,raChSys.colors_name[k]) == 0 )
- break;
- }
- if( k == raChSys.colors_count ) {
+ ARR_FIND(0,Channel_Config.colors_count,k,( strcmpi(message,Channel_Config.colors_name[k]) == 0 ));
+ if( k == Channel_Config.colors_count ) {
sprintf(atcmd_output, msg_txt(sd,1411), message);// Unknown color '%s'.
clif_displaymessage(fd, atcmd_output);
return -1;
Index: src/map/channel.c
===================================================================
--- src/map/channel.c (revision 0)
+++ src/map/channel.c (revision 0)
@@ -0,0 +1,649 @@
+// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
+// For more information, see LICENCE in the main folder
+
+#include "../common/cbasetypes.h"
+#include "../common/malloc.h"
+#include "../common/conf.h" //libconfig
+#include "../common/showmsg.h"
+#include "../common/strlib.h" //safestrncpy
+#include "../common/socket.h" //set_eof
+#include "../common/nullpo.h" //nullpo chk
+
+#include "map.h" //msg_conf
+#include "clif.h" //clif_chsys_msg
+#include "channel.h"
+#include "pc.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static DBMap* channel_db; // channels
+DBMap* channel_get_db(void){ return channel_db; } //private or public chat
+
+/*
+ * Create *channel
+ * - then add it in channel_db if type not map or ally
+ */
+struct Channel* channel_create(char *name, char *pass, unsigned char color, enum Channel_Type chantype) {
+ struct Channel* channel;
+ CREATE( channel, struct Channel, 1 ); //will exit on fail allocation
+ channel->type = chantype;
+
+ channel->users = idb_alloc(DB_OPT_BASE);
+ if( name )
+ safestrncpy(channel->name, name, CHAN_NAME_LENGTH);
+ channel->color = color;
+ if( !pass )
+ channel->pass[0] = '\0';
+ else
+ safestrncpy(channel->pass, pass, CHAN_NAME_LENGTH);
+
+ channel->opt = CHAN_OPT_BASE;
+
+ if( channel->type != CHAN_TYPE_MAP && channel->type != CHAN_TYPE_ALLY )
+ strdb_put(channel_db, channel->name, channel);
+ return channel;
+}
+
+/*
+ * Delete *channel
+ * - check if ramin user in channel and make them all quit
+ * -@TODO add return value
+ */
+void channel_delete(struct Channel *channel) {
+ if(!channel)
+ return;
+ else if( db_size(channel->users) && !Channel_Config.closing ) {
+ struct map_session_data *sd;
+ DBIterator *iter = db_iterator(channel->users);
+ for( sd = dbi_first(iter); dbi_exists(iter); sd = dbi_next(iter) ) { //for all users
+ channel_clean(channel,sd); //make all quit
+ }
+ dbi_destroy(iter);
+ if(channel->type == CHAN_TYPE_PRIVATE) //when all quit it will call delete @FIXME only the case for private
+ return;
+ }
+ db_destroy(channel->users);
+ switch(channel->type){
+ case CHAN_TYPE_MAP:
+ map[channel->m].channel = NULL;
+ aFree(channel);
+ break;
+ case CHAN_TYPE_ALLY:
+ aFree(channel);
+ break;
+ }
+ if( !Channel_Config.closing )
+ strdb_remove(channel_db, channel->name);
+}
+
+/*
+ * Make *sd join *channel
+ * - add charid to channel user list
+ * - add *channel to user channel list
+ */
+void channel_join(struct Channel *channel, struct map_session_data *sd) {
+ if(!channel || !sd)
+ return;
+ if(channel_haspc(channel,sd)) //already in here
+ return;
+
+ RECREATE(sd->channels, struct Channel *, ++sd->channel_count);
+ sd->channels[ sd->channel_count - 1 ] = channel;
+ idb_put(channel->users, sd->status.char_id, sd);
+
+ if( sd->stealth ) {
+ sd->stealth = false;
+ } else if( channel->opt & CHAN_OPT_ANNOUNCE_JOIN ) {
+ char message[60];
+ sprintf(message, "#%s '%s' joined",channel->name,sd->status.name);
+ clif_channel_msg(channel,sd,message);
+ }
+
+ /* someone is cheating, we kindly disconnect the bastard */
+ if( sd->channel_count > 200 ) {
+ set_eof(sd->fd);
+ }
+}
+
+/*
+ * Make *sd join the map channel
+ * create the map_channel if not exist
+ */
+void channel_mjoin(struct map_session_data *sd) {
+ if(!sd) return;
+
+ if( !map[sd->bl.m].channel ) {
+ map[sd->bl.m].channel = channel_create(Channel_Config.map_chname,NULL,Channel_Config.map_chcolor,CHAN_TYPE_MAP);
+ map[sd->bl.m].channel->m = sd->bl.m; //associate map
+ }
+ channel_join(map[sd->bl.m].channel,sd);
+
+ if( !( map[sd->bl.m].channel->opt & CHAN_OPT_ANNOUNCE_JOIN ) ) {
+ char mout[60];
+ sprintf(mout, msg_txt(sd,1435),Channel_Config.map_chname,map[sd->bl.m].name); // You're now in the '#%s' channel for '%s'.
+ clif_disp_onlyself(sd, mout, strlen(mout));
+ }
+}
+
+/*
+ * Make all member of guild g enter into allychan
+ */
+void channel_allgjoin(struct guild *g){
+ int i;
+ struct map_session_data *pl_sd;
+
+ if(!g) return;
+ for (i = 0; i < g->max_member; i++){ //load all guildmember
+ pl_sd = g->member[i].sd;
+ channel_gjoin(pl_sd,3);
+ }
+}
+
+/*
+ * Make *sd join the guild channel
+ * create a chan guild if not exist
+ */
+void channel_gjoin(struct map_session_data *sd, int flag){
+ struct Channel *channel;
+ struct guild *g;
+ int i;
+
+ if(!sd) return;
+
+ g = sd->guild;
+ if(!g) return;
+
+ channel = g->channel;
+ if(!channel){
+ channel = channel_create(Channel_Config.ally_chname,NULL,Channel_Config.ally_chcolor,CHAN_TYPE_ALLY);
+ g->channel = channel;
+ }
+ if(flag&1) channel_join(channel,sd); //join our guild chat
+ if(flag&2){ //join allies chat
+ for (i = 0; i < MAX_GUILDALLIANCE; i++){
+ struct guild *ag;
+ int gid = g->alliance[i].guild_id;
+ if(gid && (ag=guild_search(gid)) )
+ channel_join(ag->channel,sd);
+ }
+ }
+}
+
+/*
+ * Make *sd leave *channel and cleanup association.
+ * if no one remain in chat delete it (PRIVATE only atm)
+ */
+void channel_clean(struct Channel *channel, struct map_session_data *sd) {
+ unsigned char i;
+
+ if(!channel || !sd)
+ return;
+
+ if( channel == sd->gcbind )
+ sd->gcbind = NULL;
+
+ ARR_FIND(0, sd->channel_count, i, sd->channels[i] == channel);
+ if( i < sd->channel_count ) {
+ unsigned char cursor = i;
+ sd->channels[i] = NULL;
+ for(; i < sd->channel_count; i++ ) { //slice move list down
+ if( sd->channels[i] == NULL )
+ continue;
+ sd->channels[cursor] = sd->channels[i];
+ cursor++;
+ }
+ if ( !(sd->channel_count = cursor) ) { //if in no more chan delete db
+ aFree(sd->channels);
+ sd->channels = NULL;
+ }
+ }
+
+ idb_remove(channel->users,sd->status.char_id); //remove user for channel user list
+ if( !db_size(channel->users) && channel->type == CHAN_TYPE_PRIVATE )
+ channel_delete(channel);
+}
+
+/*
+ * type&1 : quit guild and ally
+ * type&2 : quit all in user chan lists
+ * type&4 : quit map chan
+ */
+void channel_pcquit(struct map_session_data *sd, int type){
+ int i;
+
+ if(!sd) return;
+ // Leave all chat channels.
+ if(type&1 && Channel_Config.ally_enable
+ && sd->status.guild_id
+ && !Channel_Config.closing ) //will be remove in guild_do_final
+ {
+ struct guild *g = sd->guild, *sg;
+ if( g ) {
+ if( channel_haspc(g->channel,sd) ) //leave guild chan
+ channel_clean((struct Channel *)g->channel,sd);
+ for (i = 0; i < MAX_GUILDALLIANCE; i++) { //leave all alliance chan
+ if( g->alliance[i].guild_id && (sg = guild_search(g->alliance[i].guild_id) ) ) {
+ if( channel_haspc(g->channel,sd) )
+ channel_clean((struct Channel *)sg->channel,sd);
+ break;
+ }
+ }
+ }
+ }
+ if(type&2 && sd->channel_count ) { //quit all chan
+ uint8 count = sd->channel_count;
+ for( i = count-1; i >= 0; i--) { //going backward to avoid shifting
+ channel_clean(sd->channels[i],sd);
+ }
+ }
+ if(type&4 && channel_haspc(map[sd->bl.m].channel,sd)
+ && !Channel_Config.closing ) //will be remove in map_do_final
+ {
+ channel_clean(map[sd->bl.m].channel,sd);
+ }
+}
+
+/*
+ * Format *msg from *sd to send it in *channel
+ * Also truncate extra char if msg too long (max=RACHSYS_MSG_LENGTH)
+ */
+void channel_send(struct Channel *channel, struct map_session_data *sd, char *msg) {
+ char message[CHAN_MSG_LENGTH];
+ snprintf(message, CHAN_MSG_LENGTH, "[ #%s ] %s : %s",channel->name,sd->status.name, msg);
+ clif_channel_msg(channel,sd,message);
+}
+
+/*
+ * Chk parameter for channel creation
+ * @type (bitflag)
+ * 1 : check name # + lenght
+ * 2 : check if already exist, need 1
+ * 4 : check pass lenght
+ * return
+ * 0 : success
+ * -1 : bad chan name
+ * -2 : bad chan name lenght
+ * -3 : pass given too long
+ * -4 : chan already exist
+ */
+int channel_chk(char *chname, char *chpass, int type){
+ if(type&1){ //check name
+ if( chname[0] != '#' ) return -1; // Channel name must start with '#'
+ if ( strlen(chname) < 3 || strlen(chname) > CHAN_NAME_LENGTH )
+ return -2; // Channel length must be between 3 and %d.
+ if( (type&2) && (
+ strcmpi(chname + 1,Channel_Config.map_chname) == 0
+ || strcmpi(chname + 1,Channel_Config.ally_chname) == 0
+ || strdb_exists(channel_db, chname + 1) )
+ ) {
+ return -4; // Channel '%s' already exist
+ }
+ }
+ if (type&4 && (chpass != '\0' && strlen(chpass) > CHAN_NAME_LENGTH ) ) {
+ return -3; // Channel pass can't be higher then %d.
+ }
+
+ return 0;
+}
+
+struct Channel* channel_name2channel(char *chname){
+ struct Channel *channel;
+ if(channel_chk(chname, NULL, 1)) return NULL;
+ if( !(channel = strdb_get(channel_db, chname + 1)) ) {
+ return NULL;
+ }
+ return channel;
+}
+
+int channel_haspc(struct Channel *channel,struct map_session_data *sd){
+ if(!channel || !sd) return 0;
+ return (idb_exists(channel->users, sd->status.char_id))?1:0;
+}
+
+int channel_pc_haschan(struct map_session_data *sd, struct Channel *channel){
+ int k;
+ if(!channel || !sd) return -2; //channel or player doesn't exist
+ ARR_FIND(0, sd->channel_count, k, strcmpi(channel->name,sd->channels[k]->name) == 0);
+ if( k >= sd->channel_count ) return -1;
+ return k;
+}
+
+int channel_display_list(struct map_session_data *sd, char *color){
+ struct Channel *channel;
+ char output[128];
+ int k;
+
+ if(!sd)
+ return 0;
+
+ if( color[0] != '\0' && strcmpi(color,"colors") == 0 ) {
+ char msg[40];
+ for( k = 0; k < Channel_Config.colors_count; k++ ) {
+ sprintf(msg, "[ Channel list colors ] : %s",Channel_Config.colors_name[k]);
+ clif_colormes(sd, k, msg);
+ }
+ } else {
+ DBIterator *iter;
+ bool show_all = pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ? true : false;
+ clif_displaymessage(sd->fd, msg_txt(sd,1410)); // ---- Public Channels ----
+ if( Channel_Config.map_enable ) {
+ 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 )
+ clif_displaymessage(sd->fd, output);
+ }
+ if( Channel_Config.ally_enable && sd->status.guild_id ) {
+ struct guild *g = sd->guild;
+ if( !g ) return -1; //how can this happen if status.guild_id true ?
+ sprintf(output, msg_txt(sd,1409), Channel_Config.ally_chname, db_size(((struct Channel *)g->channel)->users));// - #%s ( %d users )
+ clif_displaymessage(sd->fd, output);
+ }
+ iter = db_iterator(channel_db);
+ for(channel = dbi_first(iter); dbi_exists(iter); channel = dbi_next(iter)) {
+ if( show_all || channel->type == CHAN_TYPE_PUBLIC ) {
+ sprintf(output, msg_txt(sd,1409), channel->name, db_size(channel->users));// - #%s (%d users)
+ clif_displaymessage(sd->fd, output);
+ }
+ }
+ dbi_destroy(iter);
+ }
+ return 0;
+}
+
+int channel_pccreate(struct map_session_data *sd, char *chname, char *chpass){
+ struct Channel *channel;
+ char output[128];
+ int8 res;
+
+ if(!sd)
+ return 0;
+
+ res = channel_chk(chname,chpass,7);
+ if(res==0){ //succes
+ channel = channel_create(chname + 1,chpass,0,CHAN_TYPE_PRIVATE);
+ channel->owner = sd->status.char_id;
+ channel_join(channel,sd);
+ if( !( channel->opt & CHAN_OPT_ANNOUNCE_JOIN ) ) {
+ sprintf(output, msg_txt(sd,1403),chname); // You're now in the '%s' channel.
+ clif_displaymessage(sd->fd, output);
+ }
+ } else { //failure display cause
+ switch(res){
+ case -1: sprintf(output, msg_txt(sd,1405), CHAN_NAME_LENGTH); break;// Channel name must start with '#'.
+ case -2: sprintf(output, msg_txt(sd,1406), CHAN_NAME_LENGTH); break;// Channel length must be between 3 and %d.
+ case -3: sprintf(output, msg_txt(sd,1436), CHAN_NAME_LENGTH); break;// Channel pass can't be higher then %d.
+ case -4: sprintf(output, msg_txt(sd,1407), chname);// Channel '%s' is not available.
+ }
+ clif_displaymessage(sd->fd, output);
+ return -1;
+ }
+ return 0;
+}
+
+int channel_leave(struct map_session_data *sd, char *chname){
+ struct Channel *channel;
+ char output[128];
+
+ if(!sd)
+ return 0;
+
+ if( channel_chk(chname,NULL,1) ) {
+ clif_displaymessage(sd->fd, msg_txt(sd,1405));// Channel name must start with '#'.
+ return -1;
+ }
+ channel = channel_name2channel(chname);
+ if(channel_pc_haschan(sd,channel)<0){
+ sprintf(output, msg_txt(sd,1425),chname);// You're not part of the '%s' channel.
+ clif_displaymessage(sd->fd, output);
+ return -2; //channel doesn't exist or player don't have it
+ }
+
+ if( !Channel_Config.closing && (channel->opt & CHAN_OPT_ANNOUNCE_JOIN) ) {
+ char message[60];
+ sprintf(message, "#%s '%s' left",channel->name,sd->status.name);
+ clif_channel_msg(channel,sd,message);
+ }
+ channel_clean(channel,sd);
+
+ sprintf(output, msg_txt(sd,1426),chname); // You've left the '%s' channel.
+ clif_displaymessage(sd->fd, output);
+ return 0;
+}
+
+int channel_pccolor(struct map_session_data *sd, char *chname, char *color){
+ struct Channel *channel;
+ char output[128];
+ int k;
+
+ if(!sd)
+ return 0;
+
+ if( channel_chk(chname,NULL,1) ) {
+ clif_displaymessage(sd->fd, msg_txt(sd,1405));// Channel name must start with '#'.
+ return -1;
+ }
+ channel = channel_name2channel(chname);
+ if( !channel ) {
+ sprintf(output, msg_txt(sd,1407), chname);// Channel '%s' is not available.
+ clif_displaymessage(sd->fd, output);
+ return -1;
+ }
+
+ if( channel->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ) {
+ sprintf(output, msg_txt(sd,1412), chname);// You're not the owner of channel '%s'.
+ clif_displaymessage(sd->fd, output);
+ return -1;
+ }
+
+ ARR_FIND(0,Channel_Config.colors_count,k,( strcmpi(color,Channel_Config.colors_name[k]) == 0 ) );
+ if( k >= Channel_Config.colors_count ) {
+ sprintf(output, msg_txt(sd,1411), color);// Unknown color '%s'.
+ clif_displaymessage(sd->fd, output);
+ return -1;
+ }
+ channel->color = k;
+ sprintf(output, msg_txt(sd,1413),chname,Channel_Config.colors_name[k]);// '%s' channel color updated to '%s'.
+ clif_displaymessage(sd->fd, output);
+ return 0;
+}
+
+int channel_pcbind(struct map_session_data *sd, char *chname){
+ struct Channel *channel;
+ char output[128];
+
+ if(!sd)
+ return 0;
+
+ if( channel_chk(chname,NULL,1) ) {
+ clif_displaymessage(sd->fd, msg_txt(sd,1405));// Channel name must start with '#'.
+ return -1;
+ }
+ channel = channel_name2channel(chname);
+ if(channel_pc_haschan(sd,channel)<0){
+ sprintf(output, msg_txt(sd,1425),chname);// You're not part of the '%s' channel.
+ clif_displaymessage(sd->fd, output);
+ return -2; //channel doesn't exist or player don't have it
+ }
+ sd->gcbind = channel;
+ sprintf(output, msg_txt(sd,1431),chname); // Your global chat is now binded to the '%s' channel.
+ clif_displaymessage(sd->fd, output);
+ return 0;
+}
+
+int channel_pcunbind(struct map_session_data *sd){
+ char output[128];
+
+ if(!sd)
+ return 0;
+
+ if( sd->gcbind == NULL ) {
+ clif_displaymessage(sd->fd, msg_txt(sd,1432));// Your global chat is not binded to any channel.
+ return -1;
+ }
+ sprintf(output, msg_txt(sd,1433),sd->gcbind->name); // Your global chat is now unbinded from the '#%s' channel.
+ clif_displaymessage(sd->fd, output);
+ sd->gcbind = NULL;
+ return 0;
+}
+
+/*
+ * Read and verify configuration in confif_filename
+ * Assign table value with value
+ */
+void channel_read_config(void) {
+ config_t channels_conf;
+ config_setting_t *chsys = NULL;
+ const char *config_filename = "conf/channels.conf"; // FIXME hardcoded name
+
+ if (conf_read_file(&channels_conf, config_filename))
+ return;
+
+ chsys = config_lookup(&channels_conf, "chsys");
+
+ if (chsys != NULL) {
+ config_setting_t *settings = config_setting_get_elem(chsys, 0);
+ config_setting_t *channels;
+ config_setting_t *colors;
+ int i,k;
+ const char *map_chname, *ally_chname,*map_color, *ally_color;
+ int ally_enabled = 0, local_enabled = 0;
+ int local_autojoin = 0, ally_autojoin = 0;
+ int allow_user_channel_creation = 0;
+
+ if( !config_setting_lookup_string(settings, "map_local_channel_name", &map_chname) )
+ map_chname = "map";
+ safestrncpy(Channel_Config.map_chname, map_chname, CHAN_NAME_LENGTH);
+
+ if( !config_setting_lookup_string(settings, "ally_channel_name", &ally_chname) )
+ ally_chname = "ally";
+ safestrncpy(Channel_Config.ally_chname, ally_chname, CHAN_NAME_LENGTH);
+
+ config_setting_lookup_bool(settings, "map_local_channel", &local_enabled);
+ config_setting_lookup_bool(settings, "ally_channel_enabled", &ally_enabled);
+
+ if( local_enabled )
+ Channel_Config.map_enable = true;
+ if( ally_enabled )
+ Channel_Config.ally_enable = true;
+
+ config_setting_lookup_bool(settings, "map_local_channel_autojoin", &local_autojoin);
+ config_setting_lookup_bool(settings, "ally_channel_autojoin", &ally_autojoin);
+
+ if( local_autojoin )
+ Channel_Config.map_autojoin = true;
+ if( ally_autojoin )
+ Channel_Config.ally_autojoin = true;
+
+ config_setting_lookup_bool(settings, "allow_user_channel_creation", &allow_user_channel_creation);
+
+ if( allow_user_channel_creation )
+ Channel_Config.user_chenable = true;
+
+ if( (colors = config_setting_get_member(settings, "colors")) != NULL ) {
+ int color_count = config_setting_length(colors);
+ CREATE( Channel_Config.colors, unsigned long, color_count );
+ CREATE( Channel_Config.colors_name, char *, color_count );
+ for(i = 0; i < color_count; i++) {
+ config_setting_t *color = config_setting_get_elem(colors, i);
+ CREATE( Channel_Config.colors_name[i], char, CHAN_NAME_LENGTH );
+
+ safestrncpy(Channel_Config.colors_name[i], config_setting_name(color), CHAN_NAME_LENGTH);
+ Channel_Config.colors[i] = strtoul(config_setting_get_string_elem(colors,i),NULL,0);
+ Channel_Config.colors[i] = (Channel_Config.colors[i] & 0x0000FF) << 16 | (Channel_Config.colors[i] & 0x00FF00) | (Channel_Config.colors[i] & 0xFF0000) >> 16;//RGB to BGR
+ }
+ Channel_Config.colors_count = color_count;
+ }
+
+ config_setting_lookup_string(settings, "map_local_channel_color", &map_color);
+
+ for (k = 0; k < Channel_Config.colors_count; k++) {
+ if( strcmpi(Channel_Config.colors_name[k],map_color) == 0 )
+ break;
+ }
+
+ if( k < Channel_Config.colors_count ) {
+ Channel_Config.map_chcolor = k;
+ } else {
+ ShowError("channels.conf: unknown color '%s' for channel 'map_local_channel_color', disabling '#%s'...\n",map_color,map_chname);
+ Channel_Config.map_enable = false;
+ }
+
+ config_setting_lookup_string(settings, "ally_channel_color", &ally_color);
+
+ for (k = 0; k < Channel_Config.colors_count; k++) {
+ if( strcmpi(Channel_Config.colors_name[k],ally_color) == 0 )
+ break;
+ }
+
+ if( k < Channel_Config.colors_count ) {
+ Channel_Config.ally_chcolor = k;
+ } else {
+ ShowError("channels.conf: unknown color '%s' for channel 'ally_channel_color', disabling '#%s'...\n",map_color,ally_chname);
+ Channel_Config.ally_enable = false;
+ }
+
+ if( (channels = config_setting_get_member(settings, "default_channels")) != NULL ) {
+ int channel_count = config_setting_length(channels);
+
+ for(i = 0; i < channel_count; i++) {
+ config_setting_t *channel = config_setting_get_elem(channels, i);
+ const char *color = config_setting_get_string_elem(channels,i);
+ char *name = config_setting_name(channel);
+ struct Channel *chd;
+
+ for (k = 0; k < Channel_Config.colors_count; k++) {
+ if( strcmpi(Channel_Config.colors_name[k],color) == 0 )
+ break;
+ }
+ if( k == Channel_Config.colors_count ) {
+ ShowError("channels.conf: unknown color '%s' for channel '%s', skipping channel...\n",color,name);
+ continue;
+ }
+ if( strcmpi(name,Channel_Config.map_chname) == 0 || strcmpi(name,Channel_Config.ally_chname) == 0 || strdb_exists(channel_db, name) ) {
+ ShowError("channels.conf: duplicate channel '%s', skipping channel...\n",name);
+ continue;
+ }
+ chd = channel_create(name,NULL,k,CHAN_TYPE_PUBLIC);
+ }
+ }
+
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' channels in '"CL_WHITE"%s"CL_RESET"'.\n", db_size(channel_db), config_filename);
+ config_destroy(&channels_conf);
+ }
+}
+
+/*
+ * Initialise db and read config
+ */
+int do_init_channel(void) {
+ channel_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, CHAN_NAME_LENGTH);
+ Channel_Config.ally_enable = Channel_Config.map_enable = Channel_Config.ally_autojoin = Channel_Config.map_autojoin = false;
+ channel_read_config();
+ return 0;
+}
+
+/*
+ * Close all and cleanup
+ * NB map and guild need to cleanup their chan as well
+ */
+void do_final_channel(void) {
+ DBIterator *iter;
+ struct Channel *channel;
+ int i=0;
+
+ //delete all in chan db
+ iter = db_iterator(channel_db);
+ for( channel = dbi_first(iter); dbi_exists(iter); channel = dbi_next(iter) ) {
+ channel_delete(channel);
+ }
+ dbi_destroy(iter);
+ db_destroy(channel_db);
+
+ //delete all color thing
+ if( Channel_Config.colors_count ) {
+ for(i = 0; i < Channel_Config.colors_count; i++) {
+ aFree(Channel_Config.colors_name[i]);
+ }
+ aFree(Channel_Config.colors_name);
+ aFree(Channel_Config.colors);
+ }
+}
\ No newline at end of file
Index: src/map/battle.c
===================================================================
--- src/map/battle.c (revision 17267)
+++ src/map/battle.c (working copy)
@@ -3460,7 +3460,7 @@
#ifdef RENEWAL
if( flag.cri ){
- ATK_ADDRATE( sd->bonus.crit_atk_rate >= 100 ? sd->bonus.crit_atk_rate - 60 : 40 );
+ ATK_ADDRATE( sd->bonus.crit_atk_rate >= 100 ? sd->bonus.crit_atk_rate - 60 : 40 );
}
#endif
Index: src/map/channel.h
===================================================================
--- src/map/channel.h (revision 0)
+++ src/map/channel.h (revision 0)
@@ -0,0 +1,85 @@
+// Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
+// For more information, see LICENCE in the main folder
+
+#ifndef CHANNEL_H
+#define CHANNEL_H
+
+#include "pc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CHAN_NAME_LENGTH 20
+#define CHAN_MSG_LENGTH 150
+
+enum Channel_Opt {
+ CHAN_OPT_BASE = 0,
+ CHAN_OPT_ANNOUNCE_JOIN = 1, //display message when join or leave
+};
+
+enum Channel_Type {
+ CHAN_TYPE_PUBLIC = 0, //config file made
+ CHAN_TYPE_PRIVATE = 1, //user made
+ CHAN_TYPE_MAP = 2, //made by map
+ CHAN_TYPE_ALLY = 3, //guild
+};
+
+struct {
+ unsigned long *colors; //color avail int list
+ char **colors_name; //colors avail name list
+ unsigned char colors_count; //color avail count
+ unsigned char map_chcolor, ally_chcolor; //msg color for map, ally
+ bool map_enable, ally_enable, user_chenable; //map, ally, users channels enable ?
+ bool map_autojoin, ally_autojoin; //do user auto join in mapchange, guildjoin ?
+ char map_chname[CHAN_NAME_LENGTH], ally_chname[CHAN_NAME_LENGTH]; //channel name for map and ally
+ bool closing; //server is closing
+} Channel_Config;
+
+struct Channel {
+ char name[CHAN_NAME_LENGTH]; //channel name
+ char pass[CHAN_NAME_LENGTH]; //channel password
+ unsigned char color; //msg color
+ DBMap *users; //user charid list
+ enum Channel_Opt opt; //flag for some treatement
+ unsigned int owner; //if private type charid of who create the chan,
+ enum Channel_Type type; //type of channel
+ uint16 m; //if map type mapid
+};
+
+DBMap* channel_get_db(void);
+
+struct Channel* channel_create(char *name, char *pass, unsigned char color, enum Channel_Type chantype);
+void channel_delete(struct Channel *channel);
+
+void channel_join(struct Channel *channel, struct map_session_data *sd);
+void channel_mjoin(struct map_session_data *sd);
+void channel_gjoin(struct map_session_data *sd, int flag);
+void channel_allgjoin(struct guild *g);
+void channel_clean(struct Channel *channel, struct map_session_data *sd);
+void channel_pcquit(struct map_session_data *sd, int type);
+
+void channel_send(struct Channel *channel, struct map_session_data *sd, char *msg);
+void channel_read_config(void);
+
+int channel_chk(char *name, char *pass, int type);
+struct Channel* channel_name2channel(char *name);
+int channel_haspc(struct Channel *channel,struct map_session_data *sd);
+int channel_pc_haschan(struct map_session_data *sd, struct Channel *channel);
+int channel_pc_haschan(struct map_session_data *sd, struct Channel *channel);
+int channel_pccolor(struct map_session_data *sd, char *name, char *color);
+int channel_display_list(struct map_session_data *sd, char *color);
+int channel_pccreate(struct map_session_data *sd, char *name, char *pass);
+int channel_leave(struct map_session_data *sd, char *name);
+int channel_pcbind(struct map_session_data *sd, char *name);
+int channel_pcunbind(struct map_session_data *sd);
+
+int do_init_channel(void);
+void do_final_channel(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CHANNEL_H */
+
Index: src/map/unit.c
===================================================================
--- src/map/unit.c (revision 17267)
+++ src/map/unit.c (working copy)
@@ -18,6 +18,7 @@
#include "mercenary.h"
#include "elemental.h"
#include "skill.h"
+#include "channel.h"
#include "clif.h"
#include "duel.h"
#include "npc.h"
@@ -2294,31 +2295,8 @@
if( sd->duel_invite > 0 )
duel_reject(sd->duel_invite, sd);
- if( raChSys.ally && sd->status.guild_id ) {
- struct guild *g = sd->guild, *sg;
- if( g ) {
- if( idb_exists(((struct raChSysCh *)g->channel)->users, sd->status.char_id) )
- clif_chsys_left((struct raChSysCh *)g->channel,sd);
- for (i = 0; i < MAX_GUILDALLIANCE; i++) {
- if( g->alliance[i].guild_id && (sg = guild_search(g->alliance[i].guild_id) ) ) {
- if( idb_exists(((struct raChSysCh *)sg->channel)->users, sd->status.char_id) )
- clif_chsys_left((struct raChSysCh *)sg->channel,sd);
- break;
- }
- }
- }
- }
+ channel_pcquit(sd,7); //leave all chan
- if( sd->channel_count ) {
- uint8 ch_count = sd->channel_count;
- for( i = 0; i < ch_count; i++ ) {
- if( sd->channels[i] != NULL )
- clif_chsys_left(sd->channels[i],sd);
- }
- if( raChSys.closing )
- aFree(sd->channels);
- }
-
// Notify friends that this char logged out. [Skotlex]
map_foreachpc(clif_friendslist_toggle_sub, sd->status.account_id, sd->status.char_id, 0);
party_send_logout(sd);
Index: src/map/clif.c
===================================================================
--- src/map/clif.c (revision 17267)
+++ src/map/clif.c (working copy)
@@ -44,6 +44,7 @@
#include "mail.h"
#include "quest.h"
#include "cashshop.h"
+#include "channel.h"
#include <stdio.h>
#include <stdlib.h>
@@ -53,8 +54,6 @@
/* for clif_clearunit_delayed */
static struct eri *delay_clearunit_ers;
-static DBMap* channel_db; // channels
-DBMap* clif_get_channel_db(void){ return channel_db; }
//#define DUMP_UNKNOWN_PACKET
//#define DUMP_INVALID_PACKET
@@ -5490,52 +5489,11 @@
aFree(buf);
}
-/*==========================================
- * Channel System
- *------------------------------------------*/
-void clif_chsys_create(struct raChSysCh *channel, char *name, char *pass, unsigned char color) {
- channel->users = idb_alloc(DB_OPT_BASE);
- if( name )
- safestrncpy(channel->name, name, RACHSYS_NAME_LENGTH);
- channel->color = color;
- if( !pass )
- channel->pass[0] = '\0';
- else
- safestrncpy(channel->pass, pass, RACHSYS_NAME_LENGTH);
-
- channel->opt = raChSys_OPT_BASE;
-
- if( channel->type != raChSys_MAP && channel->type != raChSys_ALLY )
- strdb_put(channel_db, channel->name, channel);
-}
-
-void clif_chsys_join(struct raChSysCh *channel, struct map_session_data *sd) {
- RECREATE(sd->channels, struct raChSysCh *, ++sd->channel_count);
- sd->channels[ sd->channel_count - 1 ] = channel;
- idb_put(channel->users, sd->status.char_id, sd);
-
- if( sd->stealth ) {
- sd->stealth = false;
- } else if( channel->opt & raChSys_OPT_ANNOUNCE_JOIN ) {
- char message[60];
- sprintf(message, "#%s '%s' joined",channel->name,sd->status.name);
- clif_chsys_msg(channel,sd,message);
- }
-
- /* someone is cheating, we kindly disconnect the bastard */
- if( sd->channel_count > 200 ) {
- set_eof(sd->fd);
- }
-}
-
-void clif_chsys_send(struct raChSysCh *channel, struct map_session_data *sd, char *msg) {
- char message[150];
- snprintf(message, 150, "[ #%s ] %s : %s",channel->name,sd->status.name, msg);
- clif_chsys_msg(channel,sd,message);
-}
-
-void clif_chsys_msg(struct raChSysCh *channel, struct map_session_data *sd, char *msg) {
- DBIterator *iter = db_iterator(channel->users);
+/*
+ * Display *msg from *sd to all *user in channel
+ */
+void clif_channel_msg(struct Channel *channel, struct map_session_data *sd, char *msg) {
+ DBIterator *iter;
struct map_session_data *user;
unsigned short msg_len = strlen(msg) + 1;
@@ -5543,9 +5501,10 @@
WFIFOW(sd->fd,0) = 0x2C1;
WFIFOW(sd->fd,2) = msg_len + 12;
WFIFOL(sd->fd,4) = 0;
- WFIFOL(sd->fd,8) = raChSys.colors[channel->color];
+ WFIFOL(sd->fd,8) = Channel_Config.colors[channel->color];
safestrncpy((char*)WFIFOP(sd->fd,12), msg, msg_len);
+ iter = db_iterator(channel->users);
for( user = dbi_first(iter); dbi_exists(iter); user = dbi_next(iter) ) {
if( user->fd == sd->fd )
continue;
@@ -5559,225 +5518,6 @@
dbi_destroy(iter);
}
-void clif_chsys_mjoin(struct map_session_data *sd) {
- if( !map[sd->bl.m].channel ) {
- CREATE(map[sd->bl.m].channel, struct raChSysCh , 1);
- safestrncpy(map[sd->bl.m].channel->name, raChSys.local_name, RACHSYS_NAME_LENGTH);
- map[sd->bl.m].channel->type = raChSys_MAP;
- map[sd->bl.m].channel->m = sd->bl.m;
-
- clif_chsys_create(map[sd->bl.m].channel,NULL,NULL,raChSys.local_color);
- }
- clif_chsys_join(map[sd->bl.m].channel,sd);
-
- if( !( map[sd->bl.m].channel->opt & raChSys_OPT_ANNOUNCE_JOIN ) ) {
- char mout[60];
- sprintf(mout, msg_txt(sd,1435),raChSys.local_name,map[sd->bl.m].name); // You're now in the '#%s' channel for '%s'.
- clif_disp_onlyself(sd, mout, strlen(mout));
- }
-}
-
-void clif_chsys_left(struct raChSysCh *channel, struct map_session_data *sd) {
- unsigned char i;
- idb_remove(channel->users,sd->status.char_id);
-
- if( channel == sd->gcbind )
- sd->gcbind = NULL;
-
- if( !db_size(channel->users) && channel->type == raChSys_PRIVATE ) {
- clif_chsys_delete(channel);
- } else if( !raChSys.closing && (channel->opt & raChSys_OPT_ANNOUNCE_JOIN) ) {
- char message[60];
- sprintf(message, "#%s '%s' left",channel->name,sd->status.name);
- clif_chsys_msg(channel,sd,message);
- }
-
- ARR_FIND(0, sd->channel_count, i, sd->channels[i] == channel);
- if( i < sd->channel_count ) {
- unsigned char cursor = 0;
- sd->channels[i] = NULL;
- for( i = 0; i < sd->channel_count; i++ ) {
- if( sd->channels[i] == NULL )
- continue;
- if( cursor != i )
- sd->channels[cursor] = sd->channels[i];
- cursor++;
- }
- if ( !(sd->channel_count = cursor) ) {
- aFree(sd->channels);
- sd->channels = NULL;
- }
- }
-
-}
-
-void clif_chsys_delete(struct raChSysCh *channel) {
- if( db_size(channel->users) && !raChSys.closing ) {
- struct map_session_data *sd;
- unsigned char i;
- DBIterator *iter = db_iterator(channel->users);
- for( sd = dbi_first(iter); dbi_exists(iter); sd = dbi_next(iter) ) { //for all users
- ARR_FIND(0, sd->channel_count, i, sd->channels[i] == channel); //found cur chan
- if( i < sd->channel_count ) {
- unsigned char cursor = 0;
- sd->channels[i] = NULL;
- for( i = 0; i < sd->channel_count; i++ ) { //move down links
- if( sd->channels[i] == NULL )
- continue;
- if( cursor != i )
- sd->channels[cursor] = sd->channels[i];
- cursor++;
- }
- if ( !(sd->channel_count = cursor) ) { //news chan count = total
- aFree(sd->channels);
- sd->channels = NULL;
- }
- }
- }
- dbi_destroy(iter);
- }
- db_destroy(channel->users);
- if( channel->m ) {
- map[channel->m].channel = NULL;
- aFree(channel);
- } else if ( channel->type == raChSys_ALLY )
- aFree(channel);
- else if( !raChSys.closing )
- strdb_remove(channel_db, channel->name);
-}
-
-void clif_read_channels_config(void) {
- config_t channels_conf;
- config_setting_t *chsys = NULL;
- const char *config_filename = "conf/channels.conf"; // FIXME hardcoded name
-
- if (conf_read_file(&channels_conf, config_filename))
- return;
-
- chsys = config_lookup(&channels_conf, "chsys");
-
- if (chsys != NULL) {
- config_setting_t *settings = config_setting_get_elem(chsys, 0);
- config_setting_t *channels;
- config_setting_t *colors;
- int i,k;
- const char *local_name, *ally_name,
- *local_color, *ally_color;
- int ally_enabled = 0, local_enabled = 0,
- local_autojoin = 0, ally_autojoin = 0,
- allow_user_channel_creation = 0;
-
- if( !config_setting_lookup_string(settings, "map_local_channel_name", &local_name) )
- local_name = "map";
- safestrncpy(raChSys.local_name, local_name, RACHSYS_NAME_LENGTH);
-
- if( !config_setting_lookup_string(settings, "ally_channel_name", &ally_name) )
- ally_name = "ally";
- safestrncpy(raChSys.ally_name, ally_name, RACHSYS_NAME_LENGTH);
-
- config_setting_lookup_bool(settings, "map_local_channel", &local_enabled);
- config_setting_lookup_bool(settings, "ally_channel_enabled", &ally_enabled);
-
- if( local_enabled )
- raChSys.local = true;
- if( ally_enabled )
- raChSys.ally = true;
-
- config_setting_lookup_bool(settings, "map_local_channel_autojoin", &local_autojoin);
- config_setting_lookup_bool(settings, "ally_channel_autojoin", &ally_autojoin);
-
- if( local_autojoin )
- raChSys.local_autojoin = true;
- if( ally_autojoin )
- raChSys.ally_autojoin = true;
-
- config_setting_lookup_bool(settings, "allow_user_channel_creation", &allow_user_channel_creation);
-
- if( allow_user_channel_creation )
- raChSys.allow_user_channel_creation = true;
-
- if( (colors = config_setting_get_member(settings, "colors")) != NULL ) {
- int color_count = config_setting_length(colors);
- CREATE( raChSys.colors, unsigned long, color_count );
- CREATE( raChSys.colors_name, char *, color_count );
- for(i = 0; i < color_count; i++) {
- config_setting_t *color = config_setting_get_elem(colors, i);
-
- CREATE( raChSys.colors_name[i], char, RACHSYS_NAME_LENGTH );
-
- safestrncpy(raChSys.colors_name[i], config_setting_name(color), RACHSYS_NAME_LENGTH);
-
- raChSys.colors[i] = strtoul(config_setting_get_string_elem(colors,i),NULL,0);
- raChSys.colors[i] = (raChSys.colors[i] & 0x0000FF) << 16 | (raChSys.colors[i] & 0x00FF00) | (raChSys.colors[i] & 0xFF0000) >> 16;//RGB to BGR
- }
- raChSys.colors_count = color_count;
- }
-
- config_setting_lookup_string(settings, "map_local_channel_color", &local_color);
-
- for (k = 0; k < raChSys.colors_count; k++) {
- if( strcmpi(raChSys.colors_name[k],local_color) == 0 )
- break;
- }
-
- if( k < raChSys.colors_count ) {
- raChSys.local_color = k;
- } else {
- ShowError("channels.conf: unknown color '%s' for channel 'map_local_channel_color', disabling '#%s'...\n",local_color,local_name);
- raChSys.local = false;
- }
-
- config_setting_lookup_string(settings, "ally_channel_color", &ally_color);
-
- for (k = 0; k < raChSys.colors_count; k++) {
- if( strcmpi(raChSys.colors_name[k],ally_color) == 0 )
- break;
- }
-
- if( k < raChSys.colors_count ) {
- raChSys.ally_color = k;
- } else {
- ShowError("channels.conf: unknown color '%s' for channel 'ally_channel_color', disabling '#%s'...\n",local_color,ally_name);
- raChSys.ally = false;
- }
-
- if( (channels = config_setting_get_member(settings, "default_channels")) != NULL ) {
- int channel_count = config_setting_length(channels);
-
- for(i = 0; i < channel_count; i++) {
- config_setting_t *channel = config_setting_get_elem(channels, i);
- const char *name = config_setting_name(channel);
- const char *color = config_setting_get_string_elem(channels,i);
- struct raChSysCh *chd;
-
- for (k = 0; k < raChSys.colors_count; k++) {
- if( strcmpi(raChSys.colors_name[k],color) == 0 )
- break;
- }
- if( k == raChSys.colors_count ) {
- ShowError("channels.conf: unknown color '%s' for channel '%s', skipping channel...\n",color,name);
- continue;
- }
- if( strcmpi(name,raChSys.local_name) == 0 || strcmpi(name,raChSys.ally_name) == 0 || strdb_exists(channel_db, name) ) {
- ShowError("channels.conf: duplicate channel '%s', skipping channel...\n",name);
- continue;
-
- }
- CREATE( chd, struct raChSysCh, 1 );
-
- safestrncpy(chd->name, name, RACHSYS_NAME_LENGTH);
- chd->type = raChSys_PUBLIC;
-
- clif_chsys_create(chd,NULL,NULL,k);
- }
- }
-
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' channels in '"CL_WHITE"%s"CL_RESET"'.\n", db_size(channel_db), config_filename);
- config_destroy(&channels_conf);
- }
-}
-
-
/// Displays heal effect (ZC_RECOVERY).
/// 013d <var id>.W <amount>.W
/// var id:
@@ -9564,8 +9304,8 @@
status_calc_pc(sd, false); // Some conditions are map-dependent so we must recalculate
sd->state.changemap = false;
- if( raChSys.local && raChSys.local_autojoin && !map[sd->bl.m].flag.chsysnolocalaj ) {
- clif_chsys_mjoin(sd);
+ if( Channel_Config.map_enable && Channel_Config.map_autojoin && !map[sd->bl.m].flag.chmautojoin ) {
+ channel_mjoin(sd);
}
}
@@ -9867,23 +9607,12 @@
}
if( sd->gcbind ) {
- clif_chsys_send(sd->gcbind,sd,message);
+ channel_send(sd->gcbind,sd,message);
return;
} else if ( sd->fontcolor && !sd->chatID ) {
char mout[200];
- unsigned char mylen = 1;
-
- mylen += snprintf(mout, 200, "%s : %s",sd->fakename[0]?sd->fakename:sd->status.name,message);
-
- WFIFOHEAD(fd,mylen + 12);
- WFIFOW(fd,0) = 0x2C1;
- WFIFOW(fd,2) = mylen + 12;
- WFIFOL(fd,4) = sd->bl.id;
- WFIFOL(fd,8) = raChSys.colors[sd->fontcolor - 1];
- safestrncpy((char*)WFIFOP(fd,12), mout, mylen);
- clif_send(WFIFOP(fd,0), WFIFOW(fd,2), &sd->bl, AREA_WOS);
- WFIFOL(fd,4) = -sd->bl.id;
- WFIFOSET(fd, mylen + 12);
+ snprintf(mout, 200, "%s : %s",sd->fakename[0]?sd->fakename:sd->status.name,message);
+ clif_colormes(sd,sd->fontcolor-1,mout);
return;
}
@@ -10256,29 +9985,28 @@
return;
}
} else if( target[0] == '#' ) {
- struct raChSysCh *channel = NULL;
+ struct Channel *channel = NULL;
char* chname = target;
+ DBMap* channel_db = channel_get_db();
chname++;
- if( raChSys.local && strcmpi(chname, raChSys.local_name) == 0 ) {
- if( !map[sd->bl.m].channel ) {
- clif_chsys_mjoin(sd);
- }
+ if( Channel_Config.map_enable && strcmpi(chname, Channel_Config.map_chname) == 0 ) {
+ if( !map[sd->bl.m].channel ) channel_mjoin(sd);
channel = map[sd->bl.m].channel;
- } else if( raChSys.ally && sd->status.guild_id && strcmpi(chname, raChSys.ally_name) == 0 ) {
+ } else if( Channel_Config.ally_enable && sd->status.guild_id && strcmpi(chname, Channel_Config.ally_chname) == 0 ) {
struct guild *g = sd->guild;
if( !g ) return;
- channel = (struct raChSysCh *)g->channel;
+ channel = (struct Channel *)g->channel;
}
if( channel || (channel = strdb_get(channel_db,chname)) ) {
unsigned char k;
ARR_FIND(0, sd->channel_count, k, sd->channels[k] == channel);
- if( k < sd->channel_count ) {
- clif_chsys_send(channel,sd,message);
- } else if( channel->pass[0] == '\0' ) {
- clif_chsys_join(channel,sd);
- clif_chsys_send(channel,sd,message);
+ if( k < sd->channel_count ) { //in there
+ channel_send(channel,sd,message);
+ } else if( channel->pass[0] == '\0' ) { //no pass needed
+ channel_join(channel,sd);
+ channel_send(channel,sd,message);
} else {
clif_displaymessage(fd, msg_txt(sd,1402)); //You're not in that channel, type '@join <#channel_name>'
}
@@ -17374,34 +17102,9 @@
add_timer_func_list(clif_delayquit, "clif_delayquit");
delay_clearunit_ers = ers_new(sizeof(struct block_list),"clif.c::delay_clearunit_ers",ERS_OPT_CLEAR);
-
- channel_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, RACHSYS_NAME_LENGTH);
- raChSys.ally = raChSys.local = raChSys.ally_autojoin = raChSys.local_autojoin = false;
- clif_read_channels_config();
-
return 0;
}
void do_final_clif(void) {
- DBIterator *iter = db_iterator(channel_db);
- struct raChSysCh *channel;
- unsigned char i;
-
- for( channel = dbi_first(iter); dbi_exists(iter); channel = dbi_next(iter) ) {
- clif_chsys_delete(channel);
- }
-
- dbi_destroy(iter);
-
- for(i = 0; i < raChSys.colors_count; i++) {
- aFree(raChSys.colors_name[i]);
- }
-
- if( raChSys.colors_count ) {
- aFree(raChSys.colors_name);
- aFree(raChSys.colors);
- }
-
- db_destroy(channel_db);
ers_destroy(delay_clearunit_ers);
}
Index: src/map/clif.h
===================================================================
--- src/map/clif.h (revision 17267)
+++ src/map/clif.h (working copy)
@@ -6,7 +6,9 @@
#include "../common/cbasetypes.h"
#include "../common/db.h" //dbmap
+
//#include "../common/mmo.h"
+struct Channel;
struct item;
struct storage_data;
struct guild_storage;
@@ -775,56 +777,8 @@
unsigned long color_table[COLOR_MAX];
int clif_colormes(struct map_session_data * sd, enum clif_colors color, const char* msg);
-/**
- * Channel System
- **/
-#define RACHSYS_NAME_LENGTH 20
+void clif_channel_msg(struct Channel *channel, struct map_session_data *sd, char *msg);
-enum raChSysChOpt {
- raChSys_OPT_BASE = 0,
- raChSys_OPT_ANNOUNCE_JOIN = 1,
-};
-
-enum raChSysChType {
- raChSys_PUBLIC = 0,
- raChSys_PRIVATE = 1,
- raChSys_MAP = 2,
- raChSys_ALLY = 3,
-};
-
-struct {
- unsigned long *colors;
- char **colors_name;
- unsigned char colors_count;
- bool local, ally;
- bool local_autojoin, ally_autojoin;
- char local_name[RACHSYS_NAME_LENGTH], ally_name[RACHSYS_NAME_LENGTH];
- unsigned char local_color, ally_color;
- bool closing;
- bool allow_user_channel_creation;
-} raChSys;
-
-struct raChSysCh {
- char name[RACHSYS_NAME_LENGTH];
- char pass[RACHSYS_NAME_LENGTH];
- unsigned char color;
- DBMap *users;
- unsigned int opt;
- unsigned int owner;
- enum raChSysChType type;
- uint16 m;
-};
-
-struct DBMap* clif_get_channel_db(void);
-void clif_chsys_create(struct raChSysCh *channel, char *name, char *pass, unsigned char color);
-void clif_chsys_msg(struct raChSysCh *channel, struct map_session_data *sd, char *msg);
-void clif_chsys_send(struct raChSysCh *channel, struct map_session_data *sd, char *msg);
-void clif_chsys_join(struct raChSysCh *channel, struct map_session_data *sd);
-void clif_chsys_left(struct raChSysCh *channel, struct map_session_data *sd);
-void clif_chsys_delete(struct raChSysCh *channel);
-void clif_chsys_mjoin(struct map_session_data *sd);
-void clif_read_channels_config(void);
-
#define clif_menuskill_clear(sd) (sd)->menuskill_id = (sd)->menuskill_val = (sd)->menuskill_val2 = 0;
#endif /* _CLIF_H_ */
Index: src/map/guild.c
===================================================================
--- src/map/guild.c (revision 17267)
+++ src/map/guild.c (working copy)
@@ -21,6 +21,7 @@
#include "mob.h"
#include "intif.h"
#include "clif.h"
+#include "channel.h"
#include "skill.h"
#include "log.h"
@@ -499,7 +500,6 @@
DBData data;
struct map_session_data *sd;
bool guild_new = false;
- void *aChSysSave = NULL;
nullpo_ret(sg);
@@ -507,40 +507,6 @@
guild_new = true;
g=(struct guild *)aCalloc(1,sizeof(struct guild));
idb_put(guild_db,sg->guild_id,g);
- if( raChSys.ally ) {
- struct raChSysCh *channel;
-
- CREATE(channel, struct raChSysCh , 1);
- safestrncpy(channel->name, raChSys.ally_name, RACHSYS_NAME_LENGTH);
- channel->type = raChSys_ALLY;
-
- clif_chsys_create(channel,NULL,NULL,raChSys.ally_color);
- if( raChSys.ally_autojoin ) {
- struct s_mapiterator* iter = mapit_getallusers();
-
- for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) ) {
- if( sd->status.guild_id ) {
- if( sd->status.guild_id == sg->guild_id ) {
- clif_chsys_join(channel,sd);
- sd->guild = g;
- continue;
- }
-
- for (i = 0; i < MAX_GUILDALLIANCE; i++) {
- if( sg->alliance[i].guild_id == sd->status.guild_id ) {
- clif_chsys_join(channel,sd);
- break;
- }
- }
- }
- }
-
- mapit_free(iter);
- }
-
- aChSysSave = (void*)channel;
-
- }
before=*sg;
//Perform the check on the user because the first load
guild_check_member(sg);
@@ -558,13 +524,9 @@
}
} else {
before=*g;
- if( g->channel )
- aChSysSave = g->channel;
}
memcpy(g,sg,sizeof(struct guild));
- g->channel = aChSysSave;
-
if(g->max_member > MAX_GUILD) {
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);
g->max_member = MAX_GUILD;
@@ -586,6 +548,9 @@
if( sd==NULL )
continue;
sd->guild = g;
+ if( Channel_Config.ally_enable && Channel_Config.ally_autojoin ) {
+ channel_gjoin(sd,3);
+ }
if (before.guild_lv != g->guild_lv || bm != m ||
before.max_member != g->max_member) {
@@ -607,6 +572,8 @@
}
}
+
+
//Occurrence of an event
if (guild_infoevent_db->remove(guild_infoevent_db, db_i2key(sg->guild_id), &data)) {
struct eventlist *ev = db_data2ptr(&data), *ev2;
@@ -755,16 +722,8 @@
g->member[i].sd = sd;
sd->guild = g;
- if( raChSys.ally && raChSys.ally_autojoin ) {
- struct guild* sg = NULL;
- clif_chsys_join((struct raChSysCh*)g->channel,sd);
-
- for (i = 0; i < MAX_GUILDALLIANCE; i++) {
- if( g->alliance[i].guild_id && (sg = guild_search(g->alliance[i].guild_id) ) ) {
- clif_chsys_join((struct raChSysCh*)sg->channel,sd);
- break;
- }
- }
+ if( Channel_Config.ally_enable && Channel_Config.ally_autojoin ) {
+ channel_gjoin(sd,3);
}
}
}
@@ -909,13 +868,7 @@
if (sd->state.storage_flag == 2) //Close the guild storage.
storage_guild_storageclose(sd);
guild_send_dot_remove(sd);
- if( raChSys.ally ) {
- uint8 ch_count = sd->channel_count;
- for (i = 0; i < ch_count; i++) {
- if( sd->channels[i] && sd->channels[i]->type == raChSys_ALLY )
- clif_chsys_left(sd->channels[i],sd);
- }
- }
+ channel_pcquit(sd,1); //leave guild and ally chan
sd->status.guild_id = 0;
sd->guild = NULL;
sd->guild_emblem_id = 0;
@@ -1624,14 +1577,14 @@
sd[0]->guild_alliance_account=0;
}
- if (flag & 0x70) { // failure
+ if (flag & 0x70) { // failure
for(i=0;i<2-(flag&1);i++)
if( sd[i]!=NULL )
clif_guild_allianceack(sd[i],((flag>>4)==i+1)?3:4);
return 0;
}
- if (!(flag & 0x08)) { // new relationship
+ if (!(flag & 0x08)) { // new relationship
for(i=0;i<2-(flag&1);i++)
{
if(g[i]!=NULL)
@@ -1645,7 +1598,7 @@
}
}
}
- } else { // remove relationship
+ } else { // remove relationship
for(i=0;i<2-(flag&1);i++)
{
if(g[i]!=NULL)
@@ -1654,26 +1607,28 @@
if( j < MAX_GUILDALLIANCE )
g[i]->alliance[j].guild_id = 0;
}
- if (sd[i] != NULL) // notify players
+ if (sd[i] != NULL) // notify players
clif_guild_delalliance(sd[i],guild_id[1-i],(flag&1));
}
}
- if ((flag & 0x0f) == 0) { // alliance notification
+ if ((flag & 0x0f) == 0) { // alliance notification
if( sd[1]!=NULL )
clif_guild_allianceack(sd[1],2);
- } else if ((flag & 0x0f) == 1) { // enemy notification
+ } else if ((flag & 0x0f) == 1) { // enemy notification
if( sd[0]!=NULL )
clif_guild_oppositionack(sd[0],0);
}
- for (i = 0; i < 2 - (flag & 1); i++) { // Retransmission of the relationship list to all members
+ for (i = 0; i < 2 - (flag & 1); i++) { // Retransmission of the relationship list to all members
struct map_session_data *sd;
if(g[i]!=NULL)
for(j=0;j<g[i]->max_member;j++)
- if((sd=g[i]->member[j].sd)!=NULL)
+ if((sd=g[i]->member[j].sd)!=NULL){
clif_guild_allianceinfo(sd);
+ channel_gjoin(sd,2);
+ }
}
return 0;
}
@@ -1751,10 +1706,8 @@
guild_db->foreach(guild_db,guild_broken_sub,guild_id);
castle_db->foreach(castle_db,castle_guild_broken_sub,guild_id);
guild_storage_delete(guild_id);
- if( raChSys.ally ) {
- if( g->channel != NULL ) {
- clif_chsys_delete(( struct raChSysCh * )g->channel);
- }
+ if( Channel_Config.ally_enable ) {
+ channel_delete(( struct Channel * )g->channel);
}
idb_remove(guild_db,guild_id);
return 0;
@@ -2203,8 +2156,7 @@
struct guild *g;
for( g = dbi_first(iter); dbi_exists(iter); g = dbi_next(iter) ) {
- if( g->channel != NULL )
- clif_chsys_delete((struct raChSysCh *)g->channel);
+ channel_delete((struct Channel *)g->channel);
}
dbi_destroy(iter);