Index: src/map/clif.c
===================================================================
--- src/map/clif.c (revision 17265)
+++ 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);
-}
-
+/*
+ * Display *msg from *sd to all *user in channel
+ */
void clif_chsys_msg(struct raChSysCh *channel, struct map_session_data *sd, char *msg) {
- DBIterator *iter = db_iterator(channel->users);
+ DBIterator *iter;
struct map_session_data *user;
unsigned short msg_len = strlen(msg) + 1;
@@ -5546,6 +5504,7 @@
WFIFOL(sd->fd,8) = raChSys.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:
@@ -9565,7 +9305,7 @@
sd->state.changemap = false;
if( raChSys.local && raChSys.local_autojoin && !map[sd->bl.m].flag.chsysnolocalaj ) {
- clif_chsys_mjoin(sd);
+ channel_mjoin(sd);
}
}
@@ -9867,7 +9607,7 @@
}
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];
@@ -10258,12 +9998,13 @@
} else if( target[0] == '#' ) {
struct raChSysCh *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);
+ channel_mjoin(sd);
}
channel = map[sd->bl.m].channel;
} else if( raChSys.ally && sd->status.guild_id && strcmpi(chname, raChSys.ally_name) == 0 ) {
@@ -10275,10 +10016,10 @@
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);
+ channel_send(channel,sd,message);
} else if( channel->pass[0] == '\0' ) {
- clif_chsys_join(channel,sd);
- clif_chsys_send(channel,sd,message);
+ 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 +17115,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 17265)
+++ src/map/clif.h (working copy)
@@ -6,7 +6,9 @@
#include "../common/cbasetypes.h"
#include "../common/db.h" //dbmap
+
//#include "../common/mmo.h"
+struct raChSysCh;
struct item;
struct storage_data;
struct guild_storage;
@@ -775,55 +777,7 @@
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
-
-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;
Index: src/map/guild.c
===================================================================
--- src/map/guild.c (revision 17265)
+++ 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"
@@ -514,21 +515,21 @@
safestrncpy(channel->name, raChSys.ally_name, RACHSYS_NAME_LENGTH);
channel->type = raChSys_ALLY;
- clif_chsys_create(channel,NULL,NULL,raChSys.ally_color);
+ channel_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);
+ channel_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);
+ channel_join(channel,sd);
break;
}
}
@@ -757,11 +758,11 @@
if( raChSys.ally && raChSys.ally_autojoin ) {
struct guild* sg = NULL;
- clif_chsys_join((struct raChSysCh*)g->channel,sd);
+ channel_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);
+ channel_join((struct raChSysCh*)sg->channel,sd);
break;
}
}
@@ -913,7 +914,7 @@
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_left(sd->channels[i],sd);
}
}
sd->status.guild_id = 0;
@@ -1753,7 +1754,7 @@
guild_storage_delete(guild_id);
if( raChSys.ally ) {
if( g->channel != NULL ) {
- clif_chsys_delete(( struct raChSysCh * )g->channel);
+ channel_delete(( struct raChSysCh * )g->channel);
}
}
idb_remove(guild_db,guild_id);
@@ -2204,7 +2205,7 @@
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 raChSysCh *)g->channel);
}
dbi_destroy(iter);
Index: src/map/pc.c
===================================================================
--- src/map/pc.c (revision 17265)
+++ 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_*()
@@ -4769,7 +4770,7 @@
}
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_left(map[sd->bl.m].channel,sd);
}
}
Index: src/map/map.c
===================================================================
--- src/map/map.c (revision 17265)
+++ 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>
@@ -3563,7 +3565,7 @@
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 raChSysCh *)map[i].channel);
}
}
ShowStatus("Cleaned up %d maps."CL_CLL"\n", map_num);
@@ -3574,6 +3576,7 @@
do_final_atcommand();
do_final_battle();
+ do_final_channel();
do_final_chrif();
do_final_clif();
do_final_npc();
@@ -3876,6 +3879,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/Makefile.in
===================================================================
--- src/map/Makefile.in (revision 17265)
+++ 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 17265)
+++ 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"
@@ -5626,11 +5627,11 @@
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);
+ channel_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);
+ channel_left((struct raChSysCh *)sg->channel,sd);
break;
}
}
@@ -5640,7 +5641,7 @@
uint8 count = sd->channel_count;
for( i = 0; i < count; i++ ) {
if( sd->channels[i] != NULL )
- clif_chsys_left(sd->channels[i],sd);
+ channel_left(sd->channels[i],sd);
}
}
clif_authfail_fd(sd->fd, 15);
@@ -8786,7 +8787,7 @@
{
struct raChSysCh *channel;
char name[RACHSYS_NAME_LENGTH], pass[RACHSYS_NAME_LENGTH];
- DBMap* channel_db = clif_get_channel_db();
+ 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>)
@@ -8795,7 +8796,7 @@
}
if( raChSys.local && strcmpi(name + 1, raChSys.local_name) == 0 ) {
if( !map[sd->bl.m].channel ) {
- clif_chsys_mjoin(sd);
+ channel_mjoin(sd);
return 0;
} else
channel = map[sd->bl.m].channel;
@@ -8829,7 +8830,7 @@
clif_displaymessage(fd, atcmd_output);
}
- clif_chsys_join(channel,sd);
+ channel_join(channel,sd);
return 0;
}
@@ -8872,7 +8873,7 @@
struct raChSysCh *channel;
char key[RACHSYS_NAME_LENGTH], sub1[RACHSYS_NAME_LENGTH], sub2[RACHSYS_NAME_LENGTH], sub3[RACHSYS_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 ) {
@@ -8900,7 +8901,7 @@
CREATE( channel, struct raChSysCh, 1 );
- clif_chsys_create(channel,sub1 + 1,sub2,0);
+ channel_create(channel,sub1 + 1,sub2,0);
channel->owner = sd->status.char_id;
channel->type = raChSys_PRIVATE;
@@ -8910,7 +8911,7 @@
clif_displaymessage(fd, atcmd_output);
}
- clif_chsys_join(channel,sd);
+ channel_join(channel,sd);
} else if ( strcmpi(key,"list") == 0 ) {
if( sub1[0] != '\0' && strcmpi(sub1,"colors") == 0 ) {
@@ -8994,7 +8995,7 @@
clif_displaymessage(fd, atcmd_output);
return -1;
}
- clif_chsys_left(sd->channels[k],sd);
+ channel_left(sd->channels[k],sd);
sprintf(atcmd_output, msg_txt(sd,1426),sub1); // You've left the '%s' channel.
clif_displaymessage(fd, atcmd_output);
} else if ( strcmpi(key,"bindto") == 0 ) {
Index: src/map/channel.c
===================================================================
--- src/map/channel.c (revision 0)
+++ src/map/channel.c (revision 0)
@@ -0,0 +1,336 @@
+// 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 "map.h" //msg_conf
+#include "clif.h" //clif_chsys_msg
+#include "channel.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
+ */
+void channel_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);
+}
+
+/*
+ * Delete *channel
+ * - check if ramin user in channel and make them all quit
+ * -@TODO add return value
+ */
+void channel_delete(struct raChSysCh *channel) {
+ if( db_size(channel->users) && !raChSys.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_left(channel,sd); //make all quit
+ }
+ dbi_destroy(iter);
+ if(channel->type == raChSys_PRIVATE) //when all quit it will call delete @FIXME only the case for private
+ return;
+ }
+ db_destroy(channel->users);
+ switch(channel->type){
+ case raChSys_MAP:
+ map[channel->m].channel = NULL;
+ aFree(channel);
+ break;
+ case raChSys_ALLY:
+ aFree(channel);
+ break;
+ }
+ if( !raChSys.closing )
+ strdb_remove(channel_db, channel->name);
+}
+
+/*
+ * Make *sd join *channel
+ * - add charid to channel user list
+ * - add *channel to user channel list
+ * TODO ad check if not exist already, add return values
+ */
+void channel_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);
+ }
+}
+
+/*
+ * Make *sd join the map channel
+ * create the map_channel if not exist
+ */
+void channel_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;
+
+ channel_create(map[sd->bl.m].channel,NULL,NULL,raChSys.local_color);
+ }
+ channel_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));
+ }
+}
+
+/*
+ * Make *sd leave *channel and cleanup association.
+ * if no one remain in chat delete it (PRIVATE only atm)
+ */
+void channel_left(struct raChSysCh *channel, struct map_session_data *sd) {
+ unsigned char i;
+
+ if( channel == sd->gcbind )
+ sd->gcbind = NULL;
+
+ 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++ ) { //slice move list down
+ if( sd->channels[i] == NULL )
+ continue;
+ if( cursor != i )
+ 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 == raChSys_PRIVATE )
+ channel_delete(channel);
+
+}
+
+/*
+ * 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 raChSysCh *channel, struct map_session_data *sd, char *msg) {
+ char message[RACHSYS_MSG_LENGTH];
+ snprintf(message, RACHSYS_MSG_LENGTH, "[ #%s ] %s : %s",channel->name,sd->status.name, msg);
+ clif_chsys_msg(channel,sd,message);
+}
+
+/*
+ * 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 *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;
+
+ channel_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);
+ }
+}
+
+/*
+ * Initialise db and read config
+ */
+int do_init_channel(void) {
+ 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;
+ channel_read_config();
+ return 0;
+}
+
+/*
+ * Close all and cleanup
+ */
+void do_final_channel(void) {
+ DBIterator *iter;
+ struct raChSysCh *channel;
+ int i=0;
+
+ iter = db_iterator(channel_db);
+ for( channel = dbi_first(iter); dbi_exists(iter); channel = dbi_next(iter) ) {
+ channel_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);
+}
\ No newline at end of file
Index: src/map/channel.h
===================================================================
--- src/map/channel.h (revision 0)
+++ src/map/channel.h (revision 0)
@@ -0,0 +1,71 @@
+// 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 RACHSYS_NAME_LENGTH 20
+#define RACHSYS_MSG_LENGTH 150
+
+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;
+};
+
+DBMap* channel_get_db(void);
+
+void channel_create(struct raChSysCh *channel, char *name, char *pass, unsigned char color);
+void channel_delete(struct raChSysCh *channel);
+
+void channel_join(struct raChSysCh *channel, struct map_session_data *sd);
+void channel_mjoin(struct map_session_data *sd);
+void channel_left(struct raChSysCh *channel, struct map_session_data *sd);
+
+void channel_send(struct raChSysCh *channel, struct map_session_data *sd, char *msg);
+void channel_read_config(void);
+
+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 17265)
+++ 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"
@@ -2298,11 +2299,11 @@
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);
+ channel_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);
+ channel_left((struct raChSysCh *)sg->channel,sd);
break;
}
}
@@ -2313,7 +2314,7 @@
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);
+ channel_left(sd->channels[i],sd);
}
if( raChSys.closing )
aFree(sd->channels);