int channel_invite_accept(struct map_session_data *sd) { struct channel_data *cd; const struct TimerData * td; char output[CHAT_SIZE_MAX]; char *name = NULL; if( sd == NULL || sd->channel_invite_timer == INVALID_TIMER ) return 0; if( (td = get_timer(sd->channel_invite_timer)) == NULL ) { sd->channel_invite_timer = INVALID_TIMER; return 0; // Error } name = (char *)td->data; if( (cd = (struct channel_data *)strdb_get(channel_db, name)) == NULL ) { sprintf(output, msg_txt(899), name); clif_displaymessage(sd->fd, output); channel_invite_clear(sd); } else { channel_invite_clear(sd); channel_join(sd, cd->name, cd->pass, true); } return 1; }
HPExport bool HPM_Plugin_AddHook(enum HPluginHookType type, const char *target, void *hook, unsigned int pID) { struct HookingPointData *hpd; if( hp_db && (hpd = strdb_get(hp_db,target)) ) { struct HPMHookPoint **hp = NULL; int *count = NULL; if( type == HOOK_TYPE_PRE ) { hp = (struct HPMHookPoint **)((char *)&HPMHooks.list + (sizeof(struct HPMHookPoint *)*hpd->idx)); count = (int *)((char *)&HPMHooks.count + (sizeof(int)*hpd->idx)); } else { hp = (struct HPMHookPoint **)((char *)&HPMHooks.list + (sizeof(struct HPMHookPoint *)*(hpd->idx+1))); count = (int *)((char *)&HPMHooks.count + (sizeof(int)*(hpd->idx+1))); } if( hp ) { *count += 1; RECREATE(*hp, struct HPMHookPoint, *count); (*hp)[*count - 1].func = hook; (*hp)[*count - 1].pID = pID; *(hpd->sref) = hpd->tref; return true; } } return false; }
/** * Returns the named channel. * * @param name The channel name * @param sd The issuer character, for character-specific channels (i.e. map, ally) * @return a pointer to the channel, or NULL. */ struct channel_data *channel_search(const char *name, struct map_session_data *sd) { const char *realname = name; if (!realname || !*realname) return NULL; if (*realname == '#') { realname++; if (!*realname) return NULL; } if (channel->config->local && strcmpi(realname, channel->config->local_name) == 0) { if (!sd) return NULL; if (!map->list[sd->bl.m].channel) { channel->map_join(sd); } return map->list[sd->bl.m].channel; } if (channel->config->ally && strcmpi(realname, channel->config->ally_name) == 0) { if (!sd || !sd->status.guild_id || !sd->guild) return NULL; return sd->guild->channel; } return strdb_get(channel->db, realname); }
/*========================================== * Reads channels *------------------------------------------*/ static bool channel_read_channeldb(char* str[], int columns, int current) {// <channel name>,<password>,<type>,<color>,<operator id> int type, color, op; struct channel_data *cd; type = atoi(str[2]); color = atoi(str[3]); op = atoi(str[4]); if( type < 0 || type > CHN_SERVER || (type < CHN_USER && server_channel[type]) ) { ShowWarning("channel_read_channeldb: Invalid channel type or type already in use (channel %s type %d).\n", str[0], type); return false; } if( (cd = (struct channel_data *)strdb_get(channel_db, str[0])) != NULL ) { ShowWarning("channel_read_channeldb: Channel %s already exists.\n", str[0]); return false; } if( !channel_create(NULL, str[0], str[1], type, color, op) ) { ShowWarning("channel_read_channeldb: Failed to create Channel %s.\n", str[0]); return false; } return true; }
bool channel_create(struct map_session_data *sd, const char* name, const char* pass, short type, short color, int op) { struct channel_data *cd; int i = 0; if( !name || strlen(name) < 2 || strlen(name) >= NAME_LENGTH || name[0] != '#' ) { if( sd ) clif_displaymessage(sd->fd, msg_txt(801)); return false; } if( type == CHN_USER && !sd ) return false; // Operator required for user channels if( sd && type == CHN_USER && (i = channel_slot_free(sd)) < 0 ) { clif_displaymessage(sd->fd, msg_txt(800)); return false; } if( (cd = (struct channel_data *)strdb_get(channel_db, name)) != NULL ) { if( sd ) clif_displaymessage(sd->fd, msg_txt(802)); return false; // Already exists } CREATE(cd, struct channel_data, 1); cd->channel_id = ++channel_counter; safestrncpy(cd->name, name, sizeof(cd->name)); safestrncpy(cd->pass, pass, sizeof(cd->pass)); cd->type = type; cd->color = channel_color[cap_value(color,0,38)]; cd->users = 0; cd->op = 0; cd->users_db = idb_alloc(DB_OPT_BASE); if( type == CHN_USER ) { char output[128]; sprintf(output, msg_txt(803), cd->name, sd->status.name); sd->cd[i] = cd; cd->op = sd->bl.id; idb_put(cd->users_db, sd->bl.id, sd); cd->users++; clif_channel_message(cd, output, -1); } else if( type < CHN_USER ) { server_channel[type] = cd; // Quick access to main channels ShowInfo("Channel System : New channel %s created.\n", cd->name); } else cd->op = op; // Server Channel strdb_put(channel_db, cd->name, cd); return true; }
bool raconf_getboolEx(raconf rc, const char *section, const char *fallback_section, const char *key, bool _default){ char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1]; struct conf_value *v; MAKEKEY(keystr, section, key); v = strdb_get(rc->db, keystr); if(v == NULL){ MAKEKEY(keystr, fallback_section, key); v = strdb_get(rc->db, keystr); if(v == NULL){ return _default; }else{ return v->bval; } }else{ return v->bval; } }//end: raconf_getboolEx()
const char* raconf_getstr(raconf rc, const char *section, const char *key, const char *_default){ char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1]; struct conf_value *v; MAKEKEY(keystr, section, key); v = strdb_get(rc->db, keystr); if(v == NULL) return _default; else return v->strval; }//end: raconf_getstr()
/** * Lookup a channel name * @param chname: Channel name * @param sd: Player data, can be NULL, used to solve #map and #ally cases * @param flag: Lookup types (1 - Create channel if it does not exist (map or ally only), 2 - Join the channel if not joined yet (map or ally only)) * @return NULL on channel not found or channel data on success */ struct Channel* channel_name2channel(char *chname, struct map_session_data *sd, int flag){ if(channel_chk(chname, NULL, 1)) return NULL; if(sd && strcmpi(chname + 1,channel_config.map_tmpl.name) == 0){ if(flag&1 && !map[sd->bl.m].channel) map[sd->bl.m].channel = channel_create_simple(NULL,NULL,CHAN_TYPE_MAP,sd->bl.m); if(flag&2 && channel_pc_haschan(sd,map[sd->bl.m].channel) < 1) channel_mjoin(sd); return map[sd->bl.m].channel; } else if(sd && (strcmpi(chname + 1,channel_config.ally_tmpl.name) == 0) && sd->guild){ if(flag&1 && !sd->guild->channel) sd->guild->channel = channel_create_simple(NULL,NULL,CHAN_TYPE_ALLY,sd->guild->guild_id); if(flag&2 && channel_pc_haschan(sd,map[sd->bl.m].channel) < 1) channel_gjoin(sd,3); return sd->guild->channel; } else return (struct Channel*) strdb_get(channel_db, chname + 1); }
int channel_invite_timer(int tid, unsigned int tick, int id, intptr_t data) { struct channel_data *cd; struct map_session_data* sd = map_id2sd(id); char output[CHAT_SIZE_MAX]; char *name = (char *)data; if( sd && (cd = (struct channel_data *)strdb_get(channel_db, name)) != NULL ) { sprintf(output, msg_txt(701), cd->name, sd->status.name); clif_channel_message(cd, output, -1); } if( sd ) { clif_disp_onlyself(sd, msg_txt(702), strlen(msg_txt(702))); sd->channel_invite_timer = INVALID_TIMER; } if( name ) aFree(name); return 1; }
/** * @retval NULL if not found * @private */ static inline GroupSettings* name2group(const char* group_name) { return (GroupSettings*)strdb_get(pc_groupname_db, group_name); }
static bool configParse(raconf inst, const char *fileName){ FILE *fp; char line[4096]; char currentSection[SECTION_LEN]; char *p; char c; int linecnt; size_t linelen; size_t currentSection_len; fp = fopen(fileName, "r"); if(fp == NULL){ ShowError("configParse: cannot open '%s' for reading.\n", fileName); return false; } // Start with empty section: currentSection[0] = '\0'; currentSection_len = 0; // linecnt = 0; while(1){ linecnt++; if(fgets(line, sizeof(line), fp) != line) break; linelen = strlen(line); p = line; // Skip whitespaces from beginning (space and tab) _line_begin_skip_whities: c = *p; if(c == ' ' || c == '\t'){ p++; linelen--; goto _line_begin_skip_whities; } // Remove linebreaks as (cr or lf) and whitespaces from line end! _line_end_skip_whities_and_breaks: c = p[linelen-1]; if(c == '\r' || c == '\n' || c == ' ' || c == '\t'){ p[--linelen] = '\0'; goto _line_end_skip_whities_and_breaks; } // Empty line? // or line starts with comment (commented out)? if(linelen == 0 || (p[0] == '/' && p[1] == '/') || p[0] == ';') continue; // Variable names can contain: // A-Za-z-_.0-9 // // Sections start with [ .. ] (INI Style) // c = *p; // check what we have.. :) if(c == '['){ // got section! // Got Section! // Search for ] char *start = (p+1); while(1){ ++p; c = *p; if(c == '\0'){ ShowError("Syntax Error: unterminated Section name in %s:%u (expected ']')\n", fileName, linecnt); fclose(fp); return false; }else if(c == ']'){ // closing backet (section name termination) if( (p - start + 1) > (sizeof(currentSection) ) ){ ShowError("Syntax Error: Section name in %s:%u is too large (max Supported length: %u chars)\n", fileName, linecnt, sizeof(currentSection)-1); fclose(fp); return false; } // Set section! *p = '\0'; // add termination here. memcpy(currentSection, start, (p-start)+1 ); // we'll copy \0, too! (we replaced the ] backet with \0.) currentSection_len = (p-start); break; }else if( (c >= '0' && c <= '9') || (c == '-') || (c == ' ') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ){ // skip .. (allowed char / specifier) continue; }else{ ShowError("Syntax Error: Invalid Character '%c' in %s:%u (offset %u) for Section name.\n", c, fileName, linecnt, (p-line)); fclose(fp); return false; } }//endwhile: parse section name }else if( (c >= '0' && c <= '9') || (c == '-') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ){ // Got variable! // Search for '=' or ':' wich termiantes the name char *start = p; char *valuestart = NULL; size_t start_len; while(1){ ++p; c = *p; if(c == '\0'){ ShowError("Syntax Error: unterminated Variable name in %s:%u\n", fileName, linecnt); fclose(fp); return false; }else if( (c == '=') || (c == ':') ){ // got name termination *p = '\0'; // Terminate it so (start) will hold the pointer to the name. break; }else if( (c >= '0' && c <= '9') || (c == '-') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ){ // skip .. allowed char continue; }else{ ShowError("Syntax Error: Invalid Character '%c' in %s:%u (offset %u) for Variable name.\n", c, fileName, linecnt, (p-line)); fclose(fp); return false; } }//endwhile: parse var name start_len = (p-start); if(start_len >= VARNAME_LEN){ ShowError("%s:%u Variable length exceeds limit of %u Characters.\n", fileName, linecnt, VARNAME_LEN-1); fclose(fp); return false; }else if(start_len == 0){ ShowError("%s:%u Empty Variable name is not allowed.\n", fileName, linecnt); fclose(fp); return false; } valuestart = (p+1); // Skip whitespace from begin of value (tab and space) _skip_value_begin_whities: c = *valuestart; if(c == ' ' || c == '\t'){ valuestart++; goto _skip_value_begin_whities; } // Scan for value termination, // wich can be \0 or comment start (// or ; (INI) ) // p = valuestart; while(1){ c = *p; if(c == '\0'){ // Terminated by line end. break; }else if(c == '/' && p[1] == '/'){ // terminated by c++ style comment. *p = '\0'; break; }else if(c == ';'){ // terminated by ini style comment. *p = '\0'; break; } p++; }//endwhile: search var value end. // Strip whitespaces from end of value. if(valuestart != p){ // not empty! p--; _strip_value_end_whities: c = *p; if(c == ' ' || c == '\t'){ *p = '\0'; p--; goto _strip_value_end_whities; } p++; } // Buildin Hook: if( stricmp(start, "import") == 0){ if( configParse(inst, valuestart) != true){ ShowError("%s:%u - Import of '%s' failed!\n", fileName, linecnt, valuestart); } }else{ // put it to db. struct conf_value *v, *o; char key[ (SECTION_LEN+VARNAME_LEN+1+1) ]; //+1 for delimiter, +1 for termination. size_t section_len; if(*currentSection == '\0'){ // empty / none strncpy(key, "<unnamed>",9); section_len = 9; }else{ strncpy(key, currentSection, currentSection_len); section_len = currentSection_len; } key[section_len] = '.'; // Delim strncpy(&key[section_len+1], start, start_len); key[section_len + start_len + 1] = '\0'; v = makeValue(key, valuestart, (p-valuestart) ); // Try to get the old one before o = strdb_get(inst->db, key); if(o != NULL){ strdb_remove(inst->db, key); aFree(o); // } strdb_put( inst->db, key, v); } }else{ ShowError("Syntax Error: unexpected Character '%c' in %s:%u (offset %u)\n", c, fileName, linecnt, (p-line) ); fclose(fp); return false; } } fclose(fp); return true; }//end: configParse()
void channel_message(struct map_session_data *sd, const char* channel, const char* message) { struct channel_data *cd; char output[CHAT_SIZE_MAX]; struct map_session_data *p_sd; if( !sd || !message || !*message || strlen(message) < 1 ) return; if( (cd = (struct channel_data *)strdb_get(channel_db, channel)) == NULL ) { clif_displaymessage(sd->fd, msg_txt(805)); clif_displaymessage(sd->fd, msg_txt(815)); return; } if( channel_slot_get(sd,cd) < 0 ) { clif_displaymessage(sd->fd, msg_txt(816)); return; } if( message[0] == '|' && strlen(message) >= 4 && message[3] == '.' ) message += 3; if( message[0] == '.' ) { // Channel commands size_t len = strlen(message); char* option_text; if( !strncasecmp(message, ".item ", 6) && len > 0 && cd->type == CHN_VENDING && server_channel[CHN_VENDING] && vendingbot_timer < gettick() ) { struct map_session_data *pl_sd, *b_sd[MAX_SEARCH]; struct s_mapiterator* iter; struct item_data *item_array[MAX_SEARCH]; int total[MAX_SEARCH], amount[MAX_SEARCH]; unsigned int MinPrice[MAX_SEARCH], MaxPrice[MAX_SEARCH]; int i, j, count = 1; option_text = (char *)message + 6; if( (item_array[0] = itemdb_exists(atoi(option_text))) == NULL ) count = itemdb_searchname_array(item_array, MAX_SEARCH, option_text); if( count < 1 ) { clif_displaymessage(sd->fd, msg_txt(19)); return; } if( count > MAX_SEARCH ) count = MAX_SEARCH; for( i = 0; i < MAX_SEARCH; i++ ) { total[i] = amount[i] = MaxPrice[i] = 0; MinPrice[i] = battle_config.vending_max_value + 1; b_sd[i] = NULL; } iter = mapit_getallusers(); for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) ) { if( !pl_sd->vender_id ) continue; for( i = 0; i < pl_sd->vend_num; i++ ) { // Searching in the Vending List for( j = 0; j < count; j++ ) { // Compares with each search result if( pl_sd->status.cart[pl_sd->vending[i].index].nameid != item_array[j]->nameid ) continue; amount[j] += pl_sd->vending[i].amount; total[j]++; if( pl_sd->vending[i].value < MinPrice[j] ) { // Best Price MinPrice[j] = pl_sd->vending[i].value; b_sd[j] = pl_sd; } if( pl_sd->vending[i].value > MaxPrice[j] ) MaxPrice[j] = pl_sd->vending[i].value; } } } mapit_free(iter); for( i = 0; i < count; i++ ) { if( total[i] > 0 && b_sd[i] != NULL ) { sprintf(output, msg_txt(829), server_channel[CHN_VENDING]->name, item_array[i]->jname, MinPrice[i], b_sd[i]->status.name, map[b_sd[i]->bl.m].name, b_sd[i]->bl.x, b_sd[i]->bl.y, MaxPrice[i], total[i], amount[i]); clif_channel_message(cd, output, -1); } } vendingbot_timer = gettick() + 5000; // 5 Seconds Protection from flood } else if( !strncasecmp(message, ".exit", 5) ) channel_leave(sd, cd->name, true); else if( cd->op != sd->bl.id && pc_has_permission(sd,PC_PERM_CHANNEL_OPERATOR) ) return; else if( !strncasecmp(message, ".invite ", 8) && len > 11 ) { // Invite a User to the Channel option_text = (char *)message + 8; if( (p_sd = map_nick2sd(option_text)) == NULL ) clif_displaymessage(sd->fd, msg_txt(893)); else if( p_sd == sd ) clif_displaymessage(sd->fd, msg_txt(894)); else if( p_sd->state.noask ) clif_displaymessage(sd->fd, msg_txt(700)); else if( channel_slot_get(p_sd, cd) >= 0 ) clif_displaymessage(sd->fd, msg_txt(895)); else if( p_sd->channel_invite_timer != INVALID_TIMER ) clif_displaymessage(sd->fd, msg_txt(897)); else { sprintf(output, msg_txt(896), cd->name, sd->status.name, p_sd->status.name); clif_channel_message(cd, output, -1); // Notify about the invitation to the Channel sprintf(output, msg_txt(898), sd->status.name, cd->name); clif_disp_onlyself(p_sd, output, strlen(output)); // Notify Player p_sd->channel_invite_timer = add_timer(gettick() + 30000, channel_invite_timer, p_sd->bl.id, (intptr_t)aStrdup(cd->name)); } } else if( !strncasecmp(message, ".kick ", 6) && len > 9 ) { // Kick Users option_text = (char *)message + 6; if( (p_sd = map_nick2sd(option_text)) == NULL || channel_slot_get(p_sd, cd) < 0 ) clif_displaymessage(sd->fd, msg_txt(817)); else if( p_sd == sd ) clif_displaymessage(sd->fd, msg_txt(818)); else { channel_leave(p_sd, cd->name, false); sprintf(output, msg_txt(819), cd->name, p_sd->status.name); clif_channel_message(cd, output, -1); p_sd->canjoinchn_tick = gettick() + 10000; } } else if( !strncasecmp(message, ".color ", 7) && len > 7 ) { // Set Chat Room Color short color = atoi(message + 7); if( color < 1 || color > 39 ) clif_displaymessage(sd->fd, msg_txt(830)); else { cd->color = channel_color[color - 1]; sprintf(output, msg_txt(831), cd->name); clif_channel_message(cd, output, -1); } } else if( !strncasecmp(message, ".op ", 4) && len > 7 ) { option_text = (char *)message + 4; if( cd->type != CHN_USER ) clif_displaymessage(sd->fd, msg_txt(875)); else if( (p_sd = map_nick2sd(option_text)) == NULL || channel_slot_get(p_sd, cd) < 0 ) clif_displaymessage(sd->fd, msg_txt(817)); else if( p_sd == sd ) clif_displaymessage(sd->fd, msg_txt(832)); else { cd->op = p_sd->bl.id; sprintf(output, msg_txt(833), cd->name, p_sd->status.name); clif_channel_message(cd, output, -1); } } else if( !strncasecmp(message, ".pass ", 6) && len > 6 ) { option_text = trim((char *)message + 6); if( cd->type != CHN_USER ) clif_displaymessage(sd->fd, msg_txt(875)); else if( !strcmpi(option_text, "off") ) { memset(cd->pass, '\0', sizeof(cd->pass)); sprintf(output, msg_txt(834), cd->name); clif_channel_message(cd, output, -1); } else if( strlen(option_text) > 1 && strlen(option_text) < NAME_LENGTH ) { safestrncpy(cd->pass, option_text, sizeof(cd->pass)); sprintf(output, msg_txt(835), cd->name); clif_channel_message(cd, output, -1); } else clif_displaymessage(sd->fd, msg_txt(836)); } else if( !strncasecmp(message, ".close", 6) ) { if( cd->type != CHN_USER ) clif_displaymessage(sd->fd, msg_txt(875)); else channel_close(cd); } else if( !strncasecmp(message, ".list", 6) ) { DBIterator* iter = db_iterator(cd->users_db); clif_displaymessage(sd->fd, msg_txt(837)); for( p_sd = (struct map_session_data *)dbi_first(iter); dbi_exists(iter); p_sd = (struct map_session_data *)dbi_next(iter) ) clif_displaymessage(sd->fd, p_sd->status.name); dbi_destroy(iter); clif_displaymessage(sd->fd, msg_txt(838)); } else if( !strncasecmp(message, ".help", 5) ) { // Command List clif_displaymessage(sd->fd, msg_txt(839)); clif_displaymessage(sd->fd, msg_txt(840)); clif_displaymessage(sd->fd, msg_txt(841)); clif_displaymessage(sd->fd, msg_txt(842)); clif_displaymessage(sd->fd, msg_txt(843)); clif_displaymessage(sd->fd, msg_txt(844)); clif_displaymessage(sd->fd, msg_txt(845)); clif_displaymessage(sd->fd, msg_txt(846)); } else clif_displaymessage(sd->fd, msg_txt(847)); return; } snprintf(output, sizeof(output), "%s : [%s] %s", cd->name, sd->status.name, message); clif_channel_message(cd, output, -1); }
void channel_leave(struct map_session_data *sd, const char* name, bool msg) { struct channel_data *cd; char output[128]; int i; if( (cd = (struct channel_data *)strdb_get(channel_db, name)) == NULL ) return; if( (i = channel_slot_get(sd, cd)) != -1 ) { sd->cd[i] = NULL; clif_displaymessage(sd->fd, msg_txt(809)); if( cd->type != CHN_USER && msg ) { switch( cd->type ) { case CHN_MAIN: sd->channels &= ~1; break; case CHN_VENDING: sd->channels &= ~2; break; case CHN_BATTLEGROUND: sd->channels &= ~4; break; case CHN_GAMEMASTER: sd->channels &= ~8; break; } pc_setaccountreg(sd, "#CHANNEL_CONF", sd->channels); } } if( idb_get(cd->users_db, sd->bl.id) != NULL ) { idb_remove(cd->users_db, sd->bl.id); cd->users--; if( msg ) { sprintf(output, msg_txt(810), cd->name, sd->status.name); clif_channel_message(cd, output, -1); } } if( cd->type != CHN_USER ) return; if( cd->users < 1 ) { // No more users in the channel channel_close(cd); return; } if( sd->bl.id == cd->op ) { // Select another Operator struct map_session_data *pl_sd; DBIterator* iter = db_iterator(cd->users_db); cd->op = 0; if( (pl_sd = (struct map_session_data *)dbi_first(iter)) != NULL && dbi_exists(iter) ) { cd->op = pl_sd->bl.id; sprintf(output, msg_txt(811), cd->name, pl_sd->status.name); clif_channel_message(cd, output, -1); } dbi_destroy(iter); } if( cd->users <= 0 ) { ShowWarning("Channel '%s' with no users reporting %d users. Destroying it!!.\n", cd->name, cd->users); channel_close(cd); } }
void channel_join(struct map_session_data *sd, const char* name, const char* pass, bool invite) { char output[256]; struct channel_data *cd; int i = 0; if( !name || strlen(name) < 2 || strlen(name) >= NAME_LENGTH || name[0] != '#' ) { clif_displaymessage(sd->fd, msg_txt(801)); return; } if( (cd = (struct channel_data *)strdb_get(channel_db, name)) == NULL ) { clif_displaymessage(sd->fd, msg_txt(805)); return; } if( channel_slot_get(sd, cd) != -1 ) { clif_displaymessage(sd->fd, msg_txt(806)); return; } if( (i = channel_slot_free(sd)) < 0 ) { clif_displaymessage(sd->fd, msg_txt(800)); return; } if( !invite ) { if( cd->pass[0] && strcmp(cd->pass, pass) != 0 ) { // Check password only if not invited clif_displaymessage(sd->fd, msg_txt(808)); return; } if( cd->type == CHN_GAMEMASTER && pc_has_permission(sd,PC_PERM_CHANNEL_OPERATOR) ) { clif_displaymessage(sd->fd, msg_txt(703)); return; } } if( battle_config.channel_announce_join ) { sprintf(output, msg_txt(803), cd->name, sd->status.name); clif_channel_message(cd, output, -1); } sprintf(output, msg_txt(710), sd->status.name, cd->name); clif_wis_message(sd->fd, cd->name, output, strlen(output) + 1); // Joining Channel sd->cd[i] = cd; sd->canjoinchn_tick = gettick() + 10000; idb_put(cd->users_db, sd->bl.id, sd); cd->users++; if( sd->channel_invite_timer != INVALID_TIMER ) { const struct TimerData * td = get_timer(sd->channel_invite_timer); char *name = td ? (char *)td->data : NULL; if( strcmp(name, cd->name) == 0 ) channel_invite_clear(sd); // Invitation removed as the user joined the channel } if( cd->type != CHN_USER ) { switch( cd->type ) { case CHN_MAIN: sd->channels |= 1; break; case CHN_VENDING: sd->channels |= 2; break; case CHN_BATTLEGROUND: sd->channels |= 4; break; case CHN_GAMEMASTER: sd->channels |= 8; break; } pc_setaccountreg(sd, "#CHANNEL_CONF", sd->channels); } }