implement Ircdata; include "irc.m"; include "sys.m"; sys : Sys; include "string.m"; str : String; # from hash.b hashit(s:string, n:int):int { h := 0; m := len s; for(i:=0; iprint("%s[%d] = \"%s\"\n", indent, i, a[i]); } } new_users(size:int): ref Users { return ref Users(array[size] of list of ref User); } new_post(data : string) : ref Post { post : Post; fluff_list : list of string; sys = load Sys Sys->PATH; str = load String String->PATH; sys->print(">>NEW_POST>>%s<<\n", data); if(data[0] == ':') { (post.issuing_nick, data) = str->splitl(data[1:], " "); data = data[1:]; } (args, fluff) := str->splitl(data, ":"); (nil, arg_list) := sys->tokenize(args, " "); if(len fluff > 0) (nil, fluff_list) = sys->tokenize(fluff[1:], " "); post.command = str->toupper(hd arg_list); arg_list = tl arg_list; post.args = array[len arg_list + len fluff_list] of string; i := 0; for(; arg_list != nil ; arg_list = tl arg_list) post.args[i++] = hd arg_list; for(; fluff_list != nil ; fluff_list = tl fluff_list) post.args[i++] = hd fluff_list; return ref post; } Post.print(post: self ref Post) { sys = load Sys Sys->PATH; sys->print("Issuing nick: %s\n", post.issuing_nick); if(post.issuer == nil) sys->print("\tIssuer not fetched\n"); else post.issuer.print(); if(post.target == nil) sys->print("\ttarget not fetched\n"); else post.target.print(); sys->print("\t>>cmd %s\n", post.command); dump_array("\t\t", post.args); } Users.add(users: self ref Users, nick: string): ref User { existing := users.find(nick); if(existing != nil) return nil; user := ref User; user.nick = nick; user.logged_in = 0; user.registered = 1; j := hashit(nick,len users.u); users.u[j] = user :: users.u[j]; return user.copy(); } Users.find(users: self ref Users, nick : string): ref User { user := user_ref(users, nick); if(user == nil) return nil; return user.copy(); } user_ref(users: ref Users, nick : string): ref User { j := hashit(nick,len users.u); for(q := users.u[j]; q!=nil; q = tl q){ if((hd q).nick==nick) { return hd q; } } return nil; } Users.find_or_add(users: self ref Users, nick : string): ref User { user := users.find(nick); if (user == nil) { user = users.add(nick); } return user; } Users.log_in(users: self ref Users, service: ref Service, nick : string) : ref User { user := user_ref(users, nick); if(user == nil) return nil; user.logged_in = 1; service.out <-= sys->sprint(":%s PRIVMSG %s :you are now logged in", service.nick, nick); return users.find(nick); } Users.log_out(users: self ref Users, service: ref Service, nick : string) { user := user_ref(users, nick); if(user == nil) return; user.logged_in = 0; service.out <-= sys->sprint(":%s PRIVMSG %s : %s logged you out", service.nick, service.nick, nick); service.out <-= sys->sprint("%s SVS2MODE %s -r+d 0", service.nick, nick); # unreal } Users.verify_password(users: self ref Users, nick, password : string) : int { return password == "123"; } User.copy(user: self ref User) : ref User { u := ref User; u.nick = user.nick; u.logged_in = user.logged_in; return u; } User.print(user: self ref User) { sys = load Sys Sys->PATH; sys->print("Nick: \"%s\"\n", user.nick); sys->print("logged in: \"%d\"\n", user.logged_in); } Services.find(services: self ref Services, name : string): ref Service { for(srvs := services.s; srvs!=nil; srvs = tl srvs){ if((hd srvs).name==name) { return hd srvs; } } return nil; } Services.add(services: self ref Services, nick : string, out : chan of string): ref Service { str = load String String->PATH; service : ref Service; service = services.find(nick); if(service == nil) { service = ref Service; service.name = str->toupper(nick); service.nick = nick; service.out = out; service.c = array[27] of list of ref Command; # 27 magic prime services.s = service :: services.s; } return service; } Service.add_command(service: self ref Service, name: string, func: ref Func) : ref Command { if(service.c == nil) return nil; cmd : ref Command; cmd = service.find_command(name); if(cmd == nil) { cmd = ref Command; cmd.name = name; cmd.func = func; j := hashit(name, len service.c); service.c[j] = cmd :: service.c[j]; } else { cmd.func = func; } return cmd; } Service.find_command(service: self ref Service, name: string) : ref Command { if(service.c == nil) return nil; j := hashit(name, len service.c); for(cmds := service.c[j]; cmds!=nil; cmds = tl cmds){ if((hd cmds).name==name) { return hd cmds; } } return nil; } identify(service: ref Service, users : ref Users, post: ref Post) : int { if(len post.args != 3) { service.out <-= sys->sprint(":%s PRIVMSG %s :usage IDENTIFY password ", service.nick, post.issuing_nick); return 0; } if(post.issuer == nil || !users.verify_password(post.issuer.nick, post.args[2])) { service.out <-= sys->sprint(":%s PRIVMSG %s :%s not registered / bad password", service.nick, post.issuer.nick, post.issuer.nick); return 0; } post.target = users.log_in(service, post.issuer.nick); return 1; } nick(service: ref Service, users : ref Users, post: ref Post) : int { if(post.issuer == nil) return 0; user := user_ref(users, post.issuer.nick); if(user == nil) return 0; if(user.logged_in) users.log_out(service, post.issuer.nick); if(user.registered) service.out <-= sys->sprint(":%s PRIVMSG %s :this nick belongs to a registered user. To register see http://www.bangshortfilmfestival.com/new_account.html", service.nick, post.args[0]); users.add(post.args[0]); user.nick = post.args[0]; return 1; }