mirror of https://github.com/nealey/irc-bot
Move away from object model.
This commit is contained in:
parent
4ff349018d
commit
ea2fe1ed1c
58
client.ml
58
client.ml
|
@ -1,58 +0,0 @@
|
|||
let ibuf_max = 4096
|
||||
let max_outq = 50
|
||||
let max_unsent = 4096
|
||||
|
||||
type client = {outq: Queue.t;
|
||||
unsent: string ref;
|
||||
ibuf: String;
|
||||
ibuf_len: int ref;
|
||||
out_ready: unit -> unit}
|
||||
|
||||
|
||||
let new_client g fd =
|
||||
let cli = {outq = Queue.create ();
|
||||
unsent = ref "";
|
||||
ibuf = String.create ibuf_max;
|
||||
ibuf_len = ref 0;
|
||||
out_ready = fun () ->
|
||||
Unixqueue.add_resource g (Unixqueue.Wait_out fd, -.1.0)}
|
||||
in
|
||||
Unixqueue.add_resource g (Unixqueue.Wait_in fd, -.1.0);
|
||||
Unixqueue.add_handler g (handle_client_event cli);
|
||||
cli
|
||||
|
||||
|
||||
let handle_client_event cli ues esys e =
|
||||
match e with
|
||||
| Input_arrived (g, fd) ->
|
||||
let size = ibuf_max - !cli.ibuf_len in
|
||||
let len = Unix.read fd cli.ibuf !cli.ibuf_len size in
|
||||
if (len > 0) then
|
||||
begin
|
||||
cli.ibuf_len := !cli.ibuf_len + len;
|
||||
try
|
||||
split_client_input cli ues
|
||||
with Not_found ->
|
||||
if (!cli.ibuf_len = ibuf_max) then
|
||||
(* No newline found, and the buffer is full *)
|
||||
raise Buffer_overrun;
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
||||
handle_close ();
|
||||
Unix.close fd;
|
||||
ues#clear g;
|
||||
end
|
||||
| Output_readiness (g, fd) ->
|
||||
print_endline "Output ready"
|
||||
| Out_of_band (g, fd) ->
|
||||
print_endline "Amy is hotttt"
|
||||
| Timeout (g, op) ->
|
||||
print_endline "Timeout!!!1!!1 ZOMG!"
|
||||
| Signal ->
|
||||
print_endline "Signal"
|
||||
| Extra exn ->
|
||||
print_endline "Extra"
|
||||
|
||||
|
151
ircd.ml
151
ircd.ml
|
@ -1,44 +1,127 @@
|
|||
open Unixqueue
|
||||
type server = {clients_by_name: (string, client) Hashtbl.t;
|
||||
clients_by_file_descr: (Unix.file_descr, client) Hashtbl.t;
|
||||
channels_by_name: (string, channel) Hashtbl.t}
|
||||
and client = {outq: string list Queue.t;
|
||||
unsent: string ref;
|
||||
ibuf: string;
|
||||
ibuf_len: int ref;
|
||||
out_ready: unit -> unit;
|
||||
channels: channel list}
|
||||
and channel = {name: string}
|
||||
|
||||
class ircd_connection
|
||||
(ues : unix_event_system)
|
||||
?(output_timeout = -.1.0)
|
||||
?(ibuf_max = 4096)
|
||||
?(max_outq = 50)
|
||||
?(max_unsent = 4096)
|
||||
fd =
|
||||
object (self)
|
||||
inherit Connection.buffered_connection
|
||||
ues
|
||||
~output_timeout
|
||||
~ibuf_max
|
||||
~max_outq
|
||||
~max_unsent
|
||||
fd
|
||||
let dump msg a =
|
||||
prerr_endline msg;
|
||||
a
|
||||
|
||||
(* ==========================================
|
||||
* Server stuff
|
||||
*)
|
||||
let create_server () =
|
||||
{clients_by_name = Hashtbl.create 25;
|
||||
clients_by_file_descr = Hashtbl.create 25;
|
||||
channels_by_name = Hashtbl.create 10}
|
||||
|
||||
let get_client_by_name srv name =
|
||||
Hashtbl.find srv.clients_by_name name
|
||||
|
||||
let get_client_by_file_descr srv fd =
|
||||
Hashtbl.find srv.clients_by_file_descr fd
|
||||
|
||||
let get_channel_by_name srv name =
|
||||
Hashtbl.find srv.channels_by_name name
|
||||
|
||||
|
||||
(* ==========================================
|
||||
* Client stuff
|
||||
*)
|
||||
let ibuf_max = 4096
|
||||
let max_outq = 50
|
||||
let obuf_max = 4096
|
||||
|
||||
let create_client ues g fd =
|
||||
{outq = Queue.create ();
|
||||
unsent = ref "";
|
||||
ibuf = String.create ibuf_max;
|
||||
ibuf_len = ref 0;
|
||||
out_ready =
|
||||
begin
|
||||
fun () -> Unixqueue.add_resource ues g (Unixqueue.Wait_out fd, -.1.0)
|
||||
end;
|
||||
channels = []}
|
||||
|
||||
let client_shutdown ues g fd =
|
||||
Unix.close fd;
|
||||
Unixqueue.remove_resource ues g (Unixqueue.Wait_in fd);
|
||||
try
|
||||
Unixqueue.remove_resource ues g (Unixqueue.Wait_out fd);
|
||||
with Not_found ->
|
||||
()
|
||||
|
||||
let client_handle_line srv cli line =
|
||||
print_endline line
|
||||
|
||||
let client_handle_close srv cli =
|
||||
()
|
||||
|
||||
let rec client_handle_input srv cli =
|
||||
match cli.ibuf with
|
||||
| "" ->
|
||||
()
|
||||
| ibuf ->
|
||||
let p = String.index ibuf '\n' in
|
||||
let s = String.sub ibuf 0 p in
|
||||
if p >= !(cli.ibuf_len) then
|
||||
raise Not_found;
|
||||
cli.ibuf_len := !(cli.ibuf_len) - (p + 1);
|
||||
String.blit ibuf (p + 1) ibuf 0 !(cli.ibuf_len);
|
||||
client_handle_line srv cli s;
|
||||
client_handle_input srv cli
|
||||
|
||||
let create_event_handler srv =
|
||||
fun ues esys e ->
|
||||
match e with
|
||||
| Unixqueue.Input_arrived (g, fd) ->
|
||||
let cli = dump "input" get_client_by_file_descr srv fd in
|
||||
let size = dump "size" ibuf_max - !(cli.ibuf_len) in
|
||||
let len = dump "read" Unix.read fd cli.ibuf !(cli.ibuf_len) size in
|
||||
if (len > 0) then
|
||||
begin
|
||||
cli.ibuf_len := !(cli.ibuf_len) + len;
|
||||
try
|
||||
client_handle_input srv cli
|
||||
with Not_found ->
|
||||
if (!(cli.ibuf_len) = ibuf_max) then
|
||||
(* No newline found, and the buffer is full *)
|
||||
raise (Failure "Buffer overrun");
|
||||
end
|
||||
else
|
||||
client_shutdown ues g fd
|
||||
| Unixqueue.Output_readiness (g, fd) ->
|
||||
print_endline "out"
|
||||
| Unixqueue.Out_of_band (g, fd) ->
|
||||
print_endline "oob"
|
||||
| Unixqueue.Timeout (g, op) ->
|
||||
print_endline "timeout"
|
||||
| Unixqueue.Signal ->
|
||||
print_endline "signal"
|
||||
|
||||
| Unixqueue.Extra exn ->
|
||||
print_endline "extra"
|
||||
|
||||
method handle_line line =
|
||||
let parts = Pcre.split ~pat:" " line in
|
||||
match parts with
|
||||
| ["NICK"; nick] ->
|
||||
self#log ("Set nickname to " ^ nick);
|
||||
self#write [":testserver.test"; "NOTICE"; nick; ":*** Hi there."];
|
||||
self#write ["PING"; ":12345"];
|
||||
| _ ->
|
||||
self#log ("Unknown: " ^ line)
|
||||
|
||||
method die reason =
|
||||
self#log ("Dying: " ^ reason)
|
||||
end
|
||||
|
||||
let main () =
|
||||
let ues = new unix_event_system () in
|
||||
let srv = create_server () in
|
||||
let handle_event = create_event_handler srv in
|
||||
let ues = Unixqueue.create_unix_event_system () in
|
||||
let g = Unixqueue.new_group ues in
|
||||
let handle_connection fd =
|
||||
prerr_endline "hi!";
|
||||
let c = new ircd_connection ues fd in
|
||||
c#debug true
|
||||
let cli = create_client ues g fd in
|
||||
Hashtbl.replace srv.clients_by_file_descr fd cli;
|
||||
Unixqueue.add_resource ues g (Unixqueue.Wait_in fd, -.1.0);
|
||||
in
|
||||
Unixqueue.add_handler ues g handle_event;
|
||||
Connection.establish_server
|
||||
ues
|
||||
ues
|
||||
handle_connection
|
||||
(Unix.ADDR_INET (Unix.inet_addr_any, 7777));
|
||||
ues#run ()
|
||||
|
|
Loading…
Reference in New Issue