15 hchannel
*hchannel_add(const char *cname
)
20 cp
= findchannel((char*)cname
);
23 localcreatechannel(helpmodnick
, (char*)cname
);
24 cp
= findchannel((char*)cname
);
28 localjoinchannel(helpmodnick
, cp
);
29 localgetops(helpmodnick
, cp
);
32 hchan
= (hchannel
*)malloc(sizeof(hchannel
));
34 hchan
->welcome
[0] = '\0';
35 hchan
->real_channel
= cp
;
36 hchan
->flags
= H_CHANFLAGS_DEFAULT
;
37 hchan
->channel_users
= NULL
;
38 hchan
->channel_hterms
= NULL
;
39 hchan
->max_idle
= 5 * HDEF_m
;
41 hchan
->report_to
= NULL
;
44 hchan
->jf_control
= time(NULL
);
45 hchan
->lc_profile
= NULL
;
48 hchan
->htickets
= NULL
;
49 hchan
->ticket_message
= NULL
;
51 hchan
->last_activity
= time(NULL
);
52 hchan
->last_staff_activity
= time(NULL
);
53 hchan
->stats
= get_hstat_channel();
55 hchan
->next
= hchannels
;
63 for (i
=0;i
< hchan
->real_channel
->users
->hashsize
;i
++)
65 nck
= getnickbynumeric(hchan
->real_channel
->users
->content
[i
]);
66 if (!nck
) /* it's a hash, not an array */
69 if ((husr
= huser_get(nck
)) == NULL
)
70 husr
= huser_add(nck
);
72 tmp
= huser_add_channel(husr
, hchan
);
73 hchannel_add_user(hchan
, husr
);
75 if (hchan
->real_channel
->users
->content
[i
] & CUMODE_OP
)
76 tmp
->flags
|= HCUMODE_OP
;
77 if (hchan
->real_channel
->users
->content
[i
] & CUMODE_VOICE
)
78 tmp
->flags
|= HCUMODE_VOICE
;
84 int hchannel_del(hchannel
*hchan
)
86 hchannel
*tmp
, **ptr
= &hchannels
;
88 for (;*ptr
;ptr
= &(*ptr
)->next
)
96 hcensor_del_all(&(hchan
->censor
));
97 hterm_del_all(&hchan
->channel_hterms
);
98 htopic_del_all(&hchan
->topic
);
99 hstat_del_channel(hchan
);
102 while (hchan
->htickets
)
103 hticket_del(hchan
->htickets
, hchan
);
105 localpartchannel(helpmodnick
, hchan
->real_channel
, "Channel Removed");
114 int hchannel_authority(hchannel
*hchan
, struct huser_struct
*husr
)
116 if ((hchan
->flags
& H_OPER_ONLY
) && (huser_get_level(husr
) < H_OPER
))
121 hchannel
*hchannel_get_by_name(const char *cname
)
123 hchannel
*tmp
= hchannels
;
124 for (;tmp
;tmp
=tmp
->next
)
125 if (!ircd_strcmp(cname
, tmp
->real_channel
->index
->name
->content
))
130 hchannel
*hchannel_get_by_channel(channel
*chan
)
138 for (;tmp
;tmp
=tmp
->next
)
139 if (tmp
->real_channel
== chan
)
144 const char *hchannel_get_name(hchannel
*hchan
)
146 return hchan
->real_channel
->index
->name
->content
;
149 void hchannel_del_all(void)
152 hchannel_del(hchannels
);
155 hchannel_user
*hchannel_on_channel(hchannel
*hchan
, struct huser_struct
*husr
)
157 hchannel_user
*ptr
= hchan
->channel_users
;
158 for (;ptr
;ptr
= ptr
->next
)
159 if (ptr
->husr
== husr
)
164 hchannel_user
*hchannel_add_user(hchannel
*hchan
, struct huser_struct
*husr
)
166 hchannel_user
**tmp
= &(hchan
->channel_users
);
167 assert(hchannel_on_channel(hchan
, husr
) == NULL
);
169 for (;*tmp
;tmp
= &(*tmp
)->next
);
171 *tmp
= (hchannel_user
*)malloc(sizeof(hchannel_user
));
173 (*tmp
)->time_joined
= time(NULL
);
176 assert(hchannel_on_channel(hchan
, husr
) != NULL
);
181 hchannel_user
*hchannel_del_user(hchannel
*hchan
, struct huser_struct
*husr
)
183 hchannel_user
**tmp
= &(hchan
->channel_users
);
184 assert(hchannel_on_channel(hchan
, husr
) != NULL
);
186 for (;*tmp
;tmp
= &(*tmp
)->next
)
187 if ((*tmp
)->husr
== husr
)
189 hchannel_user
*ptr
= (*tmp
)->next
;
193 assert(hchannel_on_channel(hchan
, husr
) == NULL
);
199 void hchannel_remove_inactive_users(void)
201 hchannel
*hchan
= hchannels
;
203 for (;hchan
;hchan
= hchan
->next
)
205 if (hchan
->flags
& H_ANTI_IDLE
&& !(hchan
->flags
& H_PASSIVE
))
207 hchannel_user
**hchanuser
= &hchan
->channel_users
;
211 (huser_get_level((*hchanuser
)->husr
) == H_PEON
) &&
212 (time(NULL
) - huser_on_channel((*hchanuser
)->husr
,hchan
)->last_activity
>= hchan
->max_idle
) &&
213 !(on_queue((*hchanuser
)->husr
, huser_on_channel((*hchanuser
)->husr
, hchan
))) &&
214 !IsSetHost((*hchanuser
)->husr
->real_user
)
217 if (huser_on_channel((*hchanuser
)->husr
, hchan
)->flags
& H_IDLE_WARNING
)
219 const char *banmask
= hban_ban_string((*hchanuser
)->husr
->real_user
, HBAN_HOST
);
221 helpmod_setban(hchan
, banmask
, time(NULL
) + bantime
* HDEF_m
, MCB_ADD
, HLAZY
);
223 helpmod_kick(hchan
, (*hchanuser
)->husr
, "Please do not idle in %s (%dmin anti-idle tempban). If you still require assistance, please try again later.", hchannel_get_name(hchan
), bantime
);
228 helpmod_reply((*hchanuser
)->husr
, NULL
, "You are currently idle in %s. Please part the channel if you have nothing to do there", hchannel_get_name(hchan
));
229 huser_on_channel((*hchanuser
)->husr
, hchan
)->flags
|= H_IDLE_WARNING
;
233 hchanuser
= &(*hchanuser
)->next
;
237 /* Additionally, test if the channel has queue but no idle opers / staff */
238 if (hchan
->flags
& H_QUEUE
&& hchan
->flags
& H_QUEUE_TIMEOUT
)
241 for (tmp
= hchan
->channel_users
;tmp
;tmp
= tmp
->next
)
242 if (huser_get_level(tmp
->husr
) >= H_TRIAL
)
244 huser_channel
*huserchan
= huser_on_channel(tmp
->husr
, hchan
);
245 if ((time(NULL
) - huserchan
->last_activity
< HELPMOD_QUEUE_TIMEOUT
) && (huserchan
->last_activity
!= tmp
->time_joined
))
250 hchan
->flags
&= ~H_QUEUE
;
251 if (hchan
->flags
& H_REPORT
&& hchannel_is_valid(hchan
->report_to
))
252 helpmod_message_channel(hchan
->report_to
, "%s: Channel queue deactivated because of inactivity", hchannel_get_name(hchan
));
253 hchannel_conf_change(hchan
, hchan
->flags
| H_QUEUE
);
259 void hchannel_report(void)
261 hchannel
*hchan
= hchannels
;
262 for (;hchan
;hchan
= hchan
->next
)
263 if (hchan
->flags
& H_REPORT
&& !(hchan
->flags
& H_PASSIVE
) && hchannel_is_valid(hchan
->report_to
))
265 int total
= hchannel_count_users(hchan
, H_ANY
);
266 int peons
= hchannel_count_users(hchan
, H_PEON
);
267 int services
= hchannel_count_users(hchan
, H_SERVICE
);
272 if (hchan
->flags
& H_QUEUE
)
274 int peons_queue
= hchannel_count_queue(hchan
);
275 helpmod_message_channel(hchan
->report_to
, "%s: %d user%s in queue and %d user%s currently receiving support. %d Non-user%s. Average queue time %s", hchannel_get_name(hchan
), peons_queue
, (peons_queue
==1)?"":"s", peons
- peons_queue
, (peons
- peons_queue
== 1)?"":"s", total
-peons
-services
, (total
-peons
-services
== 1)?"":"s", helpmod_strtime(hqueue_average_time(hchan
)));
278 helpmod_message_channel(hchan
->report_to
, "%s: %d user%s and %d non-user%s", hchannel_get_name(hchan
), peons
, (peons
== 1)?"":"s", total
-peons
-services
, (total
-peons
-services
== 1)?"":"s");
282 void hchannel_set_topic(hchannel
*hchan
)
284 if (hchan
->flags
& H_HANDLE_TOPIC
)
285 helpmod_set_topic(hchan
, htopic_construct(hchan
->topic
));
288 void hchannels_match_accounts(void)
290 hchannel
*hchan
= hchannels
;
291 hchannel_user
*hchanuser
;
292 for (;hchan
;hchan
= hchan
->next
)
293 for (hchanuser
= hchan
->channel_users
;hchanuser
;hchanuser
= hchanuser
->next
)
294 if (hchanuser
->husr
->account
== NULL
&& IsAccount(hchanuser
->husr
->real_user
))
295 hchanuser
->husr
->account
= haccount_get_by_name(huser_get_auth(hchanuser
->husr
));
298 int hchannels_on_queue(huser
*husr
)
300 huser_channel
*huserchan
= husr
->hchannels
;
301 for (;huserchan
;huserchan
= huserchan
->next
)
302 if (on_queue(husr
, huserchan
))
307 int hchannels_on_desk(struct huser_struct
* husr
)
309 huser_channel
*huserchan
= husr
->hchannels
;
310 for (;huserchan
;huserchan
= huserchan
->next
)
311 if (on_desk(husr
, huserchan
))
316 void hchannels_dnmo(struct huser_struct
*husr
)
318 hchannel
*hchan
= hchannels
;
319 for (;hchan
;hchan
= hchan
->next
)
321 huser_channel
*huserchan
= huser_on_channel(husr
, hchan
);
322 /*if (on_queue(husr, huserchan) || on_desk(husr, huserchan))*/
323 if (huserchan
!= NULL
)
325 hchannel_user
*tmp
= NULL
, **hchanuser
= &hchan
->channel_users
;
326 for (;*hchanuser
;hchanuser
= &(*hchanuser
)->next
)
327 if ((*hchanuser
)->husr
== husr
)
330 *hchanuser
= (*hchanuser
)->next
;
335 assert(*hchanuser
!= NULL
);
336 (*hchanuser
)->next
= NULL
;
337 if (on_desk(husr
, huserchan
))
339 helpmod_channick_modes(husr
, hchan
, MC_DEVOICE
, HLAZY
);
340 huserchan
->flags
&= ~HQUEUE_DONE
;
346 int hchannel_count_users(hchannel
*hchan
, hlevel lvl
)
349 hchannel_user
*hchanuser
= hchan
->channel_users
;
350 for (;hchanuser
;hchanuser
= hchanuser
->next
)
353 else if (huser_get_level(hchanuser
->husr
) == lvl
)
358 int hchannel_count_queue(hchannel
*hchan
)
361 hchannel_user
*hchanuser
= hchan
->channel_users
;
362 for (;hchanuser
;hchanuser
= hchanuser
->next
)
364 if (on_queue(hchanuser
->husr
, huser_on_channel(hchanuser
->husr
, hchan
)))
370 int hchannel_is_valid(hchannel
*hchan
)
372 hchannel
*ptr
= hchannels
;
373 for (;ptr
;ptr
= ptr
->next
)
379 void hchannel_mode_check(hchannel
*hchan
)
381 if (((hchan
->flags
& H_MAINTAIN_M
) || (hchan
->flags
& H_QUEUE
)) && !IsModerated(hchan
->real_channel
))
382 helpmod_simple_modes(hchan
, CHANMODE_MODERATE
, 0,0);
383 else if (!((hchan
->flags
& H_MAINTAIN_M
) || (hchan
->flags
& H_QUEUE
)) && IsModerated(hchan
->real_channel
))
384 helpmod_simple_modes(hchan
, 0, CHANMODE_MODERATE
,0);
385 if (hchan
->flags
& H_MAINTAIN_I
&& !IsInviteOnly(hchan
->real_channel
))
386 helpmod_simple_modes(hchan
, CHANMODE_INVITEONLY
, 0,0);
387 else if (!(hchan
->flags
& H_MAINTAIN_I
) && IsInviteOnly(hchan
->real_channel
))
388 helpmod_simple_modes(hchan
, 0, CHANMODE_INVITEONLY
, 0);
391 void hchannel_conf_change(hchannel
*hchan
, int old_flags
)
396 for (i
=0;i
<HCHANNEL_CONF_COUNT
;i
++)
398 if ((hchan
->flags
^ old_flags
) & (1 << i
))
400 change
= (hchan
->flags
& (1 << i
))?H_ON
:H_OFF
;
404 hchannel_mode_check(hchan
);
406 helpmod_message_channel(hchan
, "Channel queue has been activated, all users enqueued");
408 helpmod_message_channel(hchan
, "Channel queue has been deactivated");
412 hchannel_mode_check(hchan
);
419 int hchannel_count(void)
421 hchannel
*hchan
= hchannels
;
423 for (;hchan
;hchan
= hchan
->next
)
428 void hchannel_activate_join_flood(hchannel
*hchan
)
430 hchannel_user
**hchanuser
= &hchan
->channel_users
;
431 helpmod_simple_modes(hchan
, CHANMODE_REGONLY
, 0, 1);
433 /* clean the channel of the already joined clients */
435 if (((*hchanuser
)->time_joined
> (time(NULL
) - 5)) && huser_get_level((*hchanuser
)->husr
) < H_STAFF
)
436 helpmod_kick(hchan
, (*hchanuser
)->husr
, "Join flood");
438 hchanuser
= &(*hchanuser
)->next
;
440 hchan
->flags
|= H_JOIN_FLOOD
;
442 scheduleoneshot(time(NULL
) + 60, &hchannel_deactivate_join_flood
, NULL
);
445 /* goes to schedule */
446 void hchannel_deactivate_join_flood()
448 hchannel
*hchan
= hchannels
;
449 for (;hchan
;hchan
= hchan
->next
)
450 if (hchan
->flags
& H_JOIN_FLOOD
)
452 helpmod_simple_modes(hchan
, 0, CHANMODE_REGONLY
, 1);
453 hchan
->flags
&= ~H_JOIN_FLOOD
;
457 const char *hchannel_get_state(hchannel
* hchan
, int mask
)
459 if (hchan
->flags
& mask
)
465 int hchannel_highlight_detection(hchannel
*hchan
, const char *message
)
467 char buffer
[512], *buffer_ptr
= buffer
, *ptr
= buffer
;
470 strcpy(buffer
, message
);
473 for (i
=0;i
<512 && buffer
[i
] != '\0';i
++)
474 if (buffer
[i
] == ',')
477 /* reset i for loop */
483 huser_channel
*tmp_huserchan
;
488 while (*buffer_ptr
&& isspace(*buffer_ptr
))
491 if (*buffer_ptr
== '@')
496 ptr
= strchr(buffer_ptr
, ' ');
502 if ((tmp
= getnickbynick(buffer_ptr
)))
503 if ((tmp_huser
= huser_get(tmp
)))
504 if ((tmp_huserchan
= huser_on_channel(tmp_huser
, hchan
)))
505 if ((tmp_huserchan
->flags
& HCUMODE_OP
) && strlen(huser_get_nick(tmp_huser
)) > 1)
520 const char *hchannel_get_sname(int flag
)
522 if (flag
< 0 || flag
> HCHANNEL_CONF_COUNT
)
528 return "Passive state";
530 return "Welcome message";
532 return "JoinFlood protection";
536 return "Verbose queue (requires queue)";
538 return "Auto queue (requires queue)";
540 return "Channel status reporting";
542 return "Pattern censor";
544 return "Lamer control";
546 return "Idle user removal";
548 return "Keep channel moderated";
550 return "Keep channel invite only";
552 return "Handle channel topic";
554 return "Calculate statistic";
556 return "Remove joining trojans";
558 return "Channel commands";
560 return "Oper only channel";
562 return "Disallow bold, underline, etc.";
564 return "Queue inactivity deactivation";
566 return "Require a ticket to join";
568 return "Send a message on ticket issue";
570 return "Excessive highlight prevention";
572 return "Error, please contact strutsi";