This error just came to be when i was re-compiling without changing anything since last compile,
using Visual C++ 2010 express, though it compiles successfully in linux (server host compiler) and on Visual C++ 2009,
Quote
1>c:\users\cyson\desktop\tro\rathena\rathena\src\map\channel.c(129): warning C4133: '=' : incompatible types - from 'Channel **' to 'raChSysCh **'
1>c:\users\cyson\desktop\tro\rathena\rathena\src\map\channel.c(130): warning C4133: '=' : incompatible types - from 'Channel *' to 'raChSysCh *'
1>c:\users\cyson\desktop\tro\rathena\rathena\src\map\channel.c(138): warning C4013: 'clif_channel_msg' undefined; assuming extern returning int
1>c:\users\cyson\desktop\tro\rathena\rathena\src\map\channel.c(161): warning C4133: '=' : incompatible types - from 'Channel *' to 'raChSysCh *'
1>c:\users\cyson\desktop\tro\rathena\rathena\src\map\channel.c(170): warning C4133: 'function' : incompatible types - from 'raChSysCh *' to 'Channel *'
1>c:\users\cyson\desktop\tro\rathena\rathena\src\map\channel.c(251): warning C4133: '==' : incompatible types - from 'raChSysCh *' to 'Channel *'
1>c:\users\cyson\desktop\tro\rathena\rathena\src\map\channel.c(254): warning C4133: '==' : incompatible types - from 'Channel *' to 'raChSysCh *'
1>c:\users\cyson\desktop\tro\rathena\rathena\src\map\channel.c(313): warning C4133: 'function' : incompatible types - from 'raChSysCh *' to 'Channel *'
1>c:\users\cyson\desktop\tro\rathena\rathena\src\map\channel.c(314): warning C4133: 'function' : incompatible types - from 'raChSysCh *' to 'Channel *'
1>c:\users\cyson\desktop\tro\rathena\rathena\src\map\channel.c(319): warning C4133: 'function' : incompatible types - from 'raChSysCh *' to 'Channel *'
1>c:\users\cyson\desktop\tro\rathena\rathena\src\map\channel.c(337): error C2039: 'channel_tick' : is not a member of 'map_session_data'
1> c:\users\cyson\desktop\tro\rathena\rathena\src\map\pc.h(111) : see declaration of 'map_session_data'
1>c:\users\cyson\desktop\tro\rathena\rathena\src\map\channel.c(349): error C2039: 'channel_tick' : is not a member of 'map_session_data'
1> c:\users\cyson\desktop\tro\rathena\rathena\src\map\pc.h(111) : see declaration of 'map_session_data'
1>c:\users\cyson\desktop\tro\rathena\rathena\src\map\channel.c(401): warning C4133: '=' : incompatible types - from 'raChSysCh *' to 'Channel *'
1>c:\users\cyson\desktop\tro\rathena\rathena\src\map\channel.c(405): warning C4133: '=' : incompatible types - from 'Channel *' to 'raChSysCh *'
1>c:\users\cyson\desktop\tro\rathena\rathena\src\map\channel.c(495): warning C4133: '=' : incompatible types - from 'raChSysCh *' to 'Channel *'
1>c:\users\cyson\desktop\tro\rathena\rathena\src\map\channel.c(765): warning C4133: '=' : incompatible types - from 'Channel *' to 'raChSysCh *'
channel.c
// 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>staticDBMap* channel_db;// channelsDBMap* channel_get_db(void){return channel_db;}struct chan_banentry {int char_id;char char_name[NAME_LENGTH];} chan_banentry;/*
* Create *channel
* - will then add it in channel_db if type not map or ally
* @name : the name channel will be given, can't be null
* @pass : can be null. if we want to restrain access
* @color : display color type
* @chantype : type of channel
* return
* NULL : creation failed
*/structChannel* channel_create(char*name,char*pass,unsignedchar color,enumChannel_Type chantype,int val){structChannel* channel;if(!name)return NULL;
CREATE( channel,structChannel,1);//will exit on fail allocation
channel->users = idb_alloc(DB_OPT_BASE);
channel->banned = idb_alloc(DB_OPT_BASE|DB_OPT_RELEASE_DATA);
channel->opt = CHAN_OPT_BASE;
channel->type = chantype;
channel->color = color;
safestrncpy(channel->name, name, CHAN_NAME_LENGTH);if(!pass)
channel->pass[0]='\0';else
safestrncpy(channel->pass,pass, CHAN_NAME_LENGTH);//ShowInfo("Create channel %s\n",channel->name);switch(channel->type){case CHAN_TYPE_MAP: channel->m = val;break;case CHAN_TYPE_ALLY: channel->gid = val;break;case CHAN_TYPE_PRIVATE: channel->owner = val;//dont break here private need to put in dbdefault: strdb_put(channel_db, channel->name, channel);}return channel;}/*
* Delete channel *channel
* - check if there is any user in channel and make them all quit
* return
* 0 : success
* -1 : invalid channel
*/int channel_delete(structChannel*channel){if(!channel)return-1;elseif( db_size(channel->users)){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,1);//make all quit}
dbi_destroy(iter);}//ShowInfo("Deleting channel %s\n",channel->name);
db_destroy(channel->users);
db_destroy(channel->banned);switch(channel->type){case CHAN_TYPE_MAP:
map[channel->m].channel = NULL;
aFree(channel);break;case CHAN_TYPE_ALLY:{struct guild *g = guild_search(channel->gid);if(g) g->channel = NULL;
aFree(channel);break;}default:
strdb_remove(channel_db, channel->name);break;}return0;}/*
* Make player *sd join a channel *channel
* - add charid to channel user list
* - add *channel to user channel list
* return
* 0 : success
* -1 : invalid channel or sd
* -2 : sd already in channel
* -3 : sd banned
*/int channel_join(structChannel*channel,struct map_session_data *sd){char output[128];if(!channel ||!sd)return-1;if(channel_haspc(channel,sd)==1)return-2;if(channel_haspcbanned(channel,sd)==1){
sprintf(output, msg_txt(sd,1438),channel->name);//You're currently banned from the '%s' channel.
clif_displaymessage(sd->fd, output);return-3;}
RECREATE(sd->channels,structChannel*,++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;}elseif( channel->opt & CHAN_OPT_ANNOUNCE_JOIN ){char message[60];
sprintf(message,"[ #%s ] '%s' has joined.",channel->name,sd->status.name);
clif_channel_msg(channel,sd,message,channel->color);}/* someone is cheating, we kindly disconnect the bastard */if( sd->channel_count >200){
set_eof(sd->fd);}return0;}/*
* Make *sd join the map channel
* create the map_channel if not exist
* return
* -1 : invalid sd
* -2 : sd already in channel (channel_join)
* -3 : sd banned (channel_join)
*/int channel_mjoin(struct map_session_data *sd){if(!sd)return-1;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,sd->bl.m);}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));}return channel_join(map[sd->bl.m].channel,sd);}/*
* Make all ally member of guild *g join our guild chan
* nb : they only join if they are into their own guild channel (if they not they probably left it)
* return
* 0 : success
* -1 : invalid guild or no channel for guild
*/int channel_ajoin(struct guild *g){int i;struct map_session_data *pl_sd;if(!g ||!g->channel)return-1;for(i =0; i < MAX_GUILDALLIANCE; i++){struct guild *ag;//allied guldstruct guild_alliance *ga =&g->alliance[i];//guild allianceif(ga->guild_id &&(ga->opposition==0)&&(ag=guild_search(ga->guild_id))){for(i =0; i < ag->max_member; i++){//load all guildmember
pl_sd = ag->member[i].sd;if(channel_haspc(ag->channel,pl_sd)==1)//only if they are in their own guildchan
channel_join(g->channel,pl_sd);}}}return0;}/*
* Make *sd join the guild channel
* create a chan guild if not exist
* return
* 0 : success
* -1 : invalid sd
* -2 : sd has no guild attached
*/int channel_gjoin(struct map_session_data *sd,int flag){structChannel*channel;struct guild *g;int i;if(!sd)return-1;
g = sd->guild;if(!g)return-2;
channel = g->channel;if(!channel){
channel = channel_create(Channel_Config.ally_chname,NULL,Channel_Config.ally_chcolor,CHAN_TYPE_ALLY,g->guild_id);
g->channel = channel;
channel_ajoin(g);}if(flag&1){
channel_join(channel,sd);//join our guild chat}if(flag&2){for(i =0; i < MAX_GUILDALLIANCE; i++){struct guild *ag;//allied guldstruct guild_alliance *ga =&g->alliance[i];//guild allianceif(ga->guild_id &&(ga->opposition==0)&&(ag=guild_search(ga->guild_id)))//only join allies
channel_join(ag->channel,sd);}}return0;}/*
* Make *sd leave *channel and cleanup association.
* - if no one remain in chat delete it
* @flag&1 called from delete do not recall delete
*return
* 0 : success
* -1 : invalid sd or channel
*/int channel_clean(structChannel*channel,struct map_session_data *sd,int flag){unsignedchar i;if(!channel ||!sd)return-1;if( channel == sd->gcbind )
sd->gcbind = NULL;
ARR_FIND(0, sd->channel_count, i, sd->channels[i]== channel);if( i < sd->channel_count ){unsignedchar cursor = i;
sd->channels[i]= NULL;for(; i < sd->channel_count; i++){//slice move list downif( sd->channels[i]== NULL )continue;if(i != cursor)
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 listif(!db_size(channel->users)&&!(flag&1)&& channel->type != CHAN_TYPE_PUBLIC )
channel_delete(channel);return0;}/*
* Make a *sd leave a type of chan.
* @type&1 : quit guild chan
* @type&2 : quit ally chans
* @type&4 : quit map chan
* @type&8 : quit all users joined chan
* return
* 0 : success
* -1 : invalid sd
*
*/int channel_pcquit(struct map_session_data *sd,int type){int i;//On closing state we could have clean all chan by sd but pcquit is more used to free unit when//he quit a map_server, not call in map_quit cause we need to cleanup when we switch map-server as wellif(!sd)return-1;// Leave all chat channels.if(type&(1|2)&&Channel_Config.ally_enable && sd->guild){//quit guild and ally chanstruct guild *g = sd->guild;if(type&1&& channel_haspc(g->channel,sd)==1){
channel_clean(g->channel,sd,0);//leave guild chan}if(type&2){struct guild *ag;//allied guildfor(i =0; i < MAX_GUILDALLIANCE; i++){//leave all alliance chanif( g->alliance[i].guild_id &&(ag = guild_search(g->alliance[i].guild_id))){if(channel_haspc(ag->channel,sd)==1)
channel_clean(ag->channel,sd,0);break;}}}}if(type&4&&Channel_Config.map_enable && channel_haspc(map[sd->bl.m].channel,sd)==1){//quit map chan
channel_clean(map[sd->bl.m].channel,sd,0);}if(type&8&& 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,0);}}return0;}/*
* Format *msg from *sd to send it in *channel
* Also truncate extra char if msg too long (max=RACHSYS_MSG_LENGTH)
* return
* 0 : success
* -1 : invalid sd, channel, or msg
* -2 : delay msg too low since last talk
*/int channel_send(structChannel*channel,struct map_session_data *sd,constchar*msg){if(!channel ||!sd ||!msg)return-1;if(!pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN)&& channel->msg_delay !=0&& DIFF_TICK(sd->channel_tick +( channel->msg_delay *1000), gettick())>0){
clif_colormes(sd,color_table[COLOR_RED],msg_txt(sd,1455));//You're talking too fast!return-2;}else{char message[CHAN_MSG_LENGTH], color;if((channel->opt)&CHAN_OPT_COLOR_OVERRIDE && sd->fontcolor)
color = sd->fontcolor;else
color = channel->color;
snprintf(message, CHAN_MSG_LENGTH,"[ #%s ] %s : %s",channel->name,sd->status.name, msg);
clif_channel_msg(channel,sd,message,color);
sd->channel_tick = gettick();}return0;}/*
* Check parameters for channel creation
* @type (bitflag)
* 1 : check name # + length
* 2 : check if already exist, need 1
* 4 : check password length
* return
* 0 : success
* -1 : bad chan name
* -2 : bad chan name length
* -3 : pass given too long
* -4 : chan already exists
*/int channel_chk(char*chname,char*chpass,int type){if(type&1){//check nameif( chname[0]!='#')return-1;if( strlen(chname)<3|| strlen(chname)> CHAN_NAME_LENGTH )return-2;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;}}if(type&4&&(chpass !='\0'&& strlen(chpass)> CHAN_NAME_LENGTH )){return-3;}return0;}/*
* Lookup to found a channel from his name.
* @chname : channel name
* @sd : can be NULL, use to solve #map and #ally case
* @flag&1 : create channel if not exist (map or ally only)
* @flag&3 : join channel if not exist (map or ally only)
* return
* NULL : channel not found
*/structChannel* channel_name2channel(char*chname,struct map_session_data *sd,int flag){structChannel*channel;if(channel_chk(chname, NULL,1))return NULL;if(sd && strcmpi(chname +1,Channel_Config.map_chname)==0){
channel = map[sd->bl.m].channel;if(flag&1&&!channel){
channel = channel_create(Channel_Config.map_chname,NULL,Channel_Config.map_chcolor,CHAN_TYPE_MAP,sd->bl.m);if(flag&2) channel_mjoin(sd);
map[sd->bl.m].channel = channel;}}elseif(sd &&(strcmpi(chname +1,Channel_Config.ally_chname)==0)&& sd->guild){
channel = sd->guild->channel;if(flag&1&&!channel){
channel = channel_create(Channel_Config.map_chname,NULL,Channel_Config.map_chcolor,CHAN_TYPE_ALLY,sd->guild->guild_id);if(flag&2) channel_gjoin(sd,3);
sd->guild->channel = channel;}}elseif(!(channel = strdb_get(channel_db, chname +1))){return NULL;}return channel;}/*
* Channel check if he has *sd in his user list
* return
* -1 : invalid sd or channel
* 0 : not found
* 1 : has pc
*/int channel_haspc(structChannel*channel,struct map_session_data *sd){if(!channel ||!sd)return-1;return(idb_exists(channel->users, sd->status.char_id))?1:0;}/*
* Channel check if *sd is banned from channel (banned ?)
* return
* -1 : invalid sd or channel
* 0 : not found
* 1 : has pc
*/int channel_haspcbanned(structChannel*channel,struct map_session_data *sd){if(!channel ||!sd)return-1;return(idb_exists(channel->banned, sd->status.char_id))?1:0;}/*
* Player *sd check if he has Channel *channel in his channel list
* return
* -1 : invalid channel or sd
* -2 : not found
* x>0 : has_chan at index x
*/int channel_pc_haschan(struct map_session_data *sd,structChannel*channel){int k;if(!channel ||!sd)return-1;//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-2;return k;}/*
* Display some info to user *sd on channels
* @options :
* colors : display availables colors for chan system
* mine : list of chan *sd is in + nb of user
* void : list of public chan + map + guild + nb of user
* return
* 0 : success
* -1 : fail
*/int channel_display_list(struct map_session_data *sd,char*options){structChannel*channel;char output[128];int k;if(!sd ||!options)return-1;//display availaible colorsif( options[0]!='\0'&& strcmpi(options,"colors")==0){char msg[40];
clif_displaymessage(sd->fd, msg_txt(sd,1444));// ---- Available Colors ----for( k =0; k <Channel_Config.colors_count; k++){
sprintf(msg, msg_txt(sd,1445),Channel_Config.colors_name[k]);// - '%s'
clif_colormes(sd,Channel_Config.colors[k],msg);}}elseif( options[0]!='\0'&& strcmpi(options,"mine")==0){//display chan I'm into
clif_displaymessage(sd->fd, msg_txt(sd,1475));// ---- My Channels ----if(!sd->channel_count)
clif_displaymessage(sd->fd, msg_txt(sd,1476));// You have not joined any channels.else{for(k=0; k<sd->channel_count; k++){
channel = sd->channels[k];
sprintf(output, msg_txt(sd,1409), channel->name, db_size(channel->users));// - #%s (%d users)
clif_displaymessage(sd->fd, output);}}}else{//display public chanelsDBIterator*iter;bool has_perm = 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(((structChannel*)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( has_perm || 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);}return0;}/*
* A user *sd is attempting to create a channel named *chname with pass *chpass
* return
* 0 : success
* -1 : fail
*/int channel_pccreate(struct map_session_data *sd,char*chname,char*chpass){structChannel*channel;char output[128];
int8 res;if(!sd ||!chname)return0;
res = channel_chk(chname,chpass,7);if(res==0){//success
channel = channel_create(chname +1,chpass,0,CHAN_TYPE_PRIVATE,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 causeswitch(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 password can't be over %d characters.case-4: sprintf(output, msg_txt(sd,1407), chname);// Channel '%s' is not available.}
clif_displaymessage(sd->fd, output);return-1;}return0;}/*
* A user *sd is attempting to delete a channel named *chname
* return
* 0 : success
* -1 : fail
*/int channel_pcdelete(struct map_session_data *sd,char*chname){structChannel*channel;char output[128];if(!sd ||!chname)return0;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,sd,0);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}
channel_delete(channel);
sprintf(output, msg_txt(sd,1448),chname);// Channel '%s' deleted.
clif_displaymessage(sd->fd, output);return0;}/*
* A user *sd is attempting to leave a channel named *chname
* return
* 0 : success
* -1 : fail
*/int channel_pcleave(struct map_session_data *sd,char*chname){structChannel*channel;char output[128];if(!sd ||!chname)return0;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,sd,0);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->color);}switch(channel->type){case CHAN_TYPE_ALLY: channel_pcquit(sd,3);break;case CHAN_TYPE_MAP: channel_pcquit(sd,4);break;default://private and public atm
channel_clean(channel,sd,0);}
sprintf(output, msg_txt(sd,1426),chname);// You've left the '%s' channel.
clif_displaymessage(sd->fd, output);return0;}/*
* A user *sd is attempting to join a channel named *chname
* return
* 0 : success
* -1 : fail
*/int channel_pcjoin(struct map_session_data *sd,char*chname,char*pass){structChannel*channel;char output[128];if(!sd ||!chname)return0;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,sd,1);if(channel){if(channel_haspc(channel,sd)==1){
sprintf(output, msg_txt(sd,1434),chname);// You're already in the '%s' channel.
clif_displaymessage(sd->fd, output);return-1;}elseif( channel->pass[0]!='\0'){//chan has a passif(strcmp(channel->pass,pass)!=0){//wrong pass entryif( pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN)){
sd->stealth =true;}else{
sprintf(output, msg_txt(sd,1401),chname,"@join");// Channel '%s' is password-protected (usage: %s <#channel_name> <password>).
clif_displaymessage(sd->fd, output);return-1;}}}}else{
sprintf(output, msg_txt(sd,1400),chname,"@join");// Unknown channel '%s' (usage: %s <#channel_name>).
clif_displaymessage(sd->fd, output);return-1;}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);}switch(channel->type){case CHAN_TYPE_ALLY: channel_gjoin(sd,3);break;case CHAN_TYPE_MAP: channel_mjoin(sd);break;default://private and public atm
channel_join(channel,sd);}return0;}/*
* A user *sd is attempting to change color with *color of a channel named *chname
* return
* 0 : success
* -1 : fail
*/int channel_pccolor(struct map_session_data *sd,char*chname,char*color){structChannel*channel;char output[128];int k;if(!sd)return0;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,sd,0);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);return0;}/*
* A user *sd is attempting to bind (make default message output display chan talk)
* from a channel named *chname
* return
* 0 : success
* -1 : fail
*/int channel_pcbind(struct map_session_data *sd,char*chname){structChannel*channel;char output[128];if(!sd)return0;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,sd,0);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);return0;}/*
* A user *sd is attempting to unbind
* return
* 0 : success
* -1 : fail
*/int channel_pcunbind(struct map_session_data *sd){char output[128];if(!sd)return0;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;return0;}/*
* A user *sd is attempting to do something with the banlist
* @flag == 0 : ban
* @flag == 1 : unban
* @flag == 2 : unbanall
* @flag == 3 : banlist
* return
* 0 : success
* -1 : fail
*/int channel_pcban(struct map_session_data *sd,char*chname,struct map_session_data *tsd,int flag){structChannel*channel;char output[128];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,sd,0);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;}if(flag !=2&& flag !=3){char banned;if(!tsd || pc_has_permission(tsd, PC_PERM_CHANNEL_ADMIN)){
sprintf(output, msg_txt(sd,1464), tsd->status.name);// Ban failed for player '%s'.
clif_displaymessage(sd->fd, output);return-1;}
banned = channel_haspcbanned(channel,tsd);if(!flag && banned==1){
sprintf(output, msg_txt(sd,1465), tsd->status.name);// Player '%s' is already banned from this channel.
clif_displaymessage(sd->fd, output);return-1;}elseif(flag==1&& banned==0){
sprintf(output, msg_txt(sd,1440), tsd->status.name);// Player '%s' is not banned from this channel.
clif_displaymessage(sd->fd, output);return-1;}}else{if(!db_size(channel->banned)){
sprintf(output, msg_txt(sd,1439), chname);// Channel '%s' contains no banned players.
clif_displaymessage(sd->fd, output);return-1;}}//let properly alter the list nowswitch(flag){case0:{struct chan_banentry *cbe;
CREATE(cbe,struct chan_banentry,1);
cbe->char_id = tsd->status.char_id;
strcpy(cbe->char_name,tsd->status.name);
idb_put(channel->banned, tsd->status.char_id, cbe);
channel_clean(channel,tsd,0);
sprintf(output, msg_txt(sd,1437),tsd->status.name,chname);// Player '%s' is banned from the '%s' channel.break;}case1:
idb_remove(channel->banned, tsd->status.char_id);
sprintf(output, msg_txt(sd,1441),tsd->status.name,chname);// Player '%s' is unbanned from the '%s' channel.break;case2:
db_clear(channel->banned);
sprintf(output, msg_txt(sd,1442),chname);// Cleared all bans from the '%s' channel.break;case3:{DBIterator*iter = db_iterator(channel->banned);struct chan_banentry *cbe;
sprintf(output, msg_txt(sd,1443), channel->name);// ---- '#%s' Ban List:
clif_displaymessage(sd->fd, output);for( cbe = dbi_first(iter); dbi_exists(iter); cbe = dbi_next(iter)){//for all users
sprintf(output,"%d: %s",cbe->char_id,cbe->char_name);
clif_displaymessage(sd->fd, output);}
dbi_destroy(iter);}return0;}
clif_displaymessage(sd->fd, output);return0;}/*
* A user *sd is attempting to set an option on channel named *chname
* @chname = channel name
* @option = available = opt_str
* @val = value to assign to option
* return
* 0 : success
* -1 : fail
*/int channel_pcsetopt(struct map_session_data *sd,char*chname,constchar*option,constchar*val){structChannel*channel;char output[128];int k, s=0;constchar* opt_str[]={"None","JoinAnnounce","MessageDelay","ColorOverride",};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,sd,0);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;}if(!option || option =='\0'){
clif_displaymessage(sd->fd, msg_txt(sd,1446));// You need to input an option.return-1;}
s = ARRAYLENGTH(opt_str);
ARR_FIND(1,s,k,( strncmpi(option,opt_str[k],3)==0));//we only cmp 3 letter atmif( k >= s ){
sprintf(output, msg_txt(sd,1447), option);// Unknown channel option '%s'.
clif_displaymessage(sd->fd, output);
clif_displaymessage(sd->fd, msg_txt(sd,1414));// ---- Available options:for( k =1; k < s; k++){
sprintf(output, msg_txt(sd,1445), opt_str[k]);// - '%s'
clif_displaymessage(sd->fd, output);}return-1;}if( val[0]=='\0'){if( k == CHAN_OPT_MSG_DELAY ){
sprintf(output, msg_txt(sd,1466), opt_str[k]);// Input the number of seconds (0-10) for the '%s' option.
clif_displaymessage(sd->fd, output);return-1;}elseif( channel->opt & k ){
sprintf(output, msg_txt(sd,1449), opt_str[k],opt_str[k]);// Option '%s' is already enabled (use '@channel setopt %s 0' to disable).
clif_displaymessage(sd->fd, output);return-1;}else{
channel->opt |= k;
sprintf(output, msg_txt(sd,1450), opt_str[k],channel->name);// Option '%s' is enabled for channel '#%s'.
clif_displaymessage(sd->fd, output);}}else{int v = atoi(val);if( k == CHAN_OPT_MSG_DELAY ){if( v <0|| v >10){
sprintf(output, msg_txt(sd,1451), v, opt_str[k]);// Value '%d' for option '%s' is out of range (limit 0-10).
clif_displaymessage(sd->fd, output);return-1;}if( v ==0){
channel->opt &=~ k;
channel->msg_delay =0;
sprintf(output, msg_txt(sd,1453), opt_str[k],channel->name,v);// Option '%s' is disabled for channel '#%s'.
clif_displaymessage(sd->fd, output);}else{
channel->opt |= k;
channel->msg_delay = v;
sprintf(output, msg_txt(sd,1452), opt_str[k],channel->name,v);// Option '%s' is enabled for channel '#%s' at %d seconds.
clif_displaymessage(sd->fd, output);}}else{if( v ){if( channel->opt & k ){
sprintf(output, msg_txt(sd,1449), opt_str[k],opt_str[k]);// Option '%s' is already enabled (use '@channel setopt %s 0' to disable).
clif_displaymessage(sd->fd, output);return-1;}else{
channel->opt |= k;
sprintf(output, msg_txt(sd,1450), opt_str[k],channel->name);// Option '%s' is enabled for channel '#%s'.
clif_displaymessage(sd->fd, output);}}else{if(!(channel->opt & k)){
sprintf(output, msg_txt(sd,1450), opt_str[k],channel->name);// Option '%s' is enabled for channel '#%s'.
clif_displaymessage(sd->fd, output);return-1;}else{
channel->opt &=~ k;
sprintf(output, msg_txt(sd,1453), opt_str[k],channel->name);// Option '%s' is disabled for channel '#%s'.
clif_displaymessage(sd->fd, output);}}}}return0;}/*
* 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;constchar*config_filename ="conf/channels.conf";// FIXME hardcoded nameif(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;constchar*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,unsignedlong, 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 '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 'ally_channel_color', disabling '#%s'...\n",ally_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);constchar*color = config_setting_get_string_elem(channels,i);char*name = config_setting_name(channel);structChannel*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,0);}}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
* return
* 0 : success
*/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();return0;}/*
* Close all and cleanup
* NB map and guild need to cleanup their chan as well
*/void do_final_channel(void){DBIterator*iter;structChannel*channel;int i=0;//delete all in remaining 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);//at this point all user should have left their channel (private and public should be gone)
db_destroy(channel_db);//delete all color thingif(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);}}
channel.h
// 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 150enumChannel_Opt{
CHAN_OPT_BASE =0,
CHAN_OPT_ANNOUNCE_JOIN =1,//display message when join or leave
CHAN_OPT_MSG_DELAY =2,
CHAN_OPT_COLOR_OVERRIDE =3,};enumChannel_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{unsignedlong*colors;//color avail int listchar**colors_name;//colors avail name listunsignedchar colors_count;//color avail countunsignedchar map_chcolor, ally_chcolor;//msg color for map, allybool 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 allybool closing;//server is closing}Channel_Config;structChannel{char name[CHAN_NAME_LENGTH];//channel namecharpass[CHAN_NAME_LENGTH];//channel passwordunsignedchar color;//msg colorDBMap*users;//users in channel charid listDBMap*banned;//users banned from channel charid listenumChannel_Opt opt;//flag for some treatementenumChannel_Type type;//type of channelunsignedint owner;//if chan_type private charid of creator
uint16 m;//if chan_type map guild_idint gid;//if chan_type guild type guild_idunsignedchar msg_delay;//delay in second if opt_msg_delay};DBMap* channel_get_db(void);structChannel* channel_create(char*name,char*pass,unsignedchar color,enumChannel_Type chantype,int val);int channel_delete(structChannel*channel);int channel_join(structChannel*channel,struct map_session_data *sd);int channel_mjoin(struct map_session_data *sd);int channel_gjoin(struct map_session_data *sd,int flag);int channel_ajoin(struct guild *g);int channel_clean(structChannel*channel,struct map_session_data *sd,int flag);int channel_pcquit(struct map_session_data *sd,int type);int channel_send(structChannel*channel,struct map_session_data *sd,constchar*msg);void channel_read_config(void);int channel_chk(char*name,char*pass,int type);structChannel* channel_name2channel(char*chname,struct map_session_data *sd,int flag);int channel_haspc(structChannel*channel,struct map_session_data *sd);int channel_haspcbanned(structChannel*channel,struct map_session_data *sd);int channel_pc_haschan(struct map_session_data *sd,structChannel*channel);int channel_display_list(struct map_session_data *sd,char*option);int channel_pccreate(struct map_session_data *sd,char*chname,char*pass);int channel_pcdelete(struct map_session_data *sd,char*chname);int channel_pcjoin(struct map_session_data *sd,char*chname,char*pass);int channel_pcleave(struct map_session_data *sd,char*chname);int channel_pccolor(struct map_session_data *sd,char*chname,char*color);int channel_pcbind(struct map_session_data *sd,char*chname);int channel_pcunbind(struct map_session_data *sd);int channel_pcban(struct map_session_data *sd,char*chname,struct map_session_data *tsd,int flag);int channel_pcsetopt(struct map_session_data *sd,char*chname,constchar*option,constchar*val);int do_init_channel(void);void do_final_channel(void);#ifdef __cplusplus
}#endif#endif/* CHANNEL_H */
these files were not touched ever since the clean trunk has been downloaded
don't have a clue on how to fix this since i generally edit skill.c battle.c atcommand.c and status.c only, please help
Question
chowking
This error just came to be when i was re-compiling without changing anything since last compile,
using Visual C++ 2010 express, though it compiles successfully in linux (server host compiler) and on Visual C++ 2009,
channel.c
channel.h
these files were not touched ever since the clean trunk has been downloaded
don't have a clue on how to fix this since i generally edit skill.c battle.c atcommand.c and status.c only, please help
Edited by chowking0 answers to this question
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.