@program ProtoNet.MUF 1 10000 d i $def PNSNOERROR 0 $def PNSEINTR 10004 $def PNSEBADF 10009 $def PNSEMFILE 10024 $def PNSEWOULDBLOCK 10035 $def PNSEINPROGRESS 10036 $def PNSEALREADY 10037 $def PNSENOTSOCK 10038 $def PNSEDESTADDRREQ 10039 $def PNSEBADDGRAM 10040 $def PNSEBADCALL 10041 $def PNSENOHANDLER 10042 $def PNSEPROTONOSUPPORT 10043 $def PNSEREMOTEERR 10045 $def PNSENETDOWN 10050 $def PNSENETUNREACH 10051 $def PNSECONNABORTED 10053 $def PNSECONNRESET 10054 $def PNSEISCONN 10056 $def PNSENOTCONN 10057 $def PNSESHUTDOWN 10058 $def PNSETIMEDOUT 10060 $def PNSECONNREFUSED 10061 $def PNSETOKENREQD 10080 $def PNSETOKENINVALID 10081 $def PNSVERNOTSUPPORTED 10092 $def PNSHOST_NOT_FOUND 11001 $def PNSTRY_AGAIN 11002 $def PNSEUNKNOWN 11111 $pubdef PNSNOERROR 0 $pubdef PNSEINTR 10004 $pubdef PNSEBADF 10009 $pubdef PNSEACCESS 10013 $pubdef PNSEFAULT 10014 $pubdef PNSEINVAL 10022 $pubdef PNSEMFILE 10024 $pubdef PNSEWOULDBLOCK 10035 $pubdef PNSEINPROGRESS 10036 $pubdef PNSEALREADY 10037 $pubdef PNSENOTSOCK 10038 $pubdef PNSEDESTADDRREQ 10039 $pubdef PNSEBADDGRAM 10040 $pubdef PNSEBADCALL 10041 $pubdef PNSENOHANDLER 10042 $pubdef PNSEPROTONOSUPPORT 10043 $pubdef PNSEREMOTEERR 10045 $pubdef PNSENETDOWN 10050 $pubdef PNSENETUNREACH 10051 $pubdef PNSECONNABORTED 10053 $pubdef PNSECONNRESET 10054 $pubdef PNSEISCONN 10056 $pubdef PNSENOTCONN 10057 $pubdef PNSESHUTDOWN 10058 $pubdef PNSETIMEDOUT 10060 $pubdef PNSECONNREFUSED 10061 $pubdef PNSETOKENREQD 10080 $pubdef PNSETOKENINVALID 10081 $pubdef PNSVERNOTSUPPORTED 10092 $pubdef PNSHOST_NOT_FOUND 11001 $pubdef PNSTRY_AGAIN 11002 $pubdef PNSEUNKNOWN 11111 $include $lib/alynna $author Alynna $version 1.0 $def VERSION { "Proto.NET v" prog "_version" getprop }cat $def logwall ".NET: " swap strcat logstatus $def +cr 10 itoc strcat $def server? prog "@server" getprop $def closesock clearsock $def RPC_INIT var! token var! port var! hostname var! host var! muck var! name $pubdef RPC_INIT var! token var! port var! hostname var! host var! muck var! name ( How to set up a protodns server -- must be root 1. Add to /etc/inetd.conf 8853 stream tcp nowait root /usr/sbin/tcpd /usr/local/bin/protodns 2. Upload this file to your server as /usr/local/bin/protodns #!/bin/bash read REQUEST dig +short $REQUEST 3. chmod 755 /usr/local/bin/protodns 4. killall -HUP inetd If you dont have root, you can use someone elses protodns server, but ask the admin first. ) ( Public Functions: bcast[ arr:stack str:progfunc -- ] dgram[ arr:stack str:muck str:progfunc -- ] rpc[ arr:stack str:muck str:progfunc -- arr:rstack ] ) ( globals ) var clientsarray $def clients clientsarray ! lvar param lvar listener $def msgnum 4 strcut swap pop atoi : scansockets[ -- ] clientsarray @ not if 0 array_make clientsarray ! then { clientsarray @ foreach swap pop dup sockcheck -1 = if pop then repeat }array clientsarray ! prog getpids foreach swap pop "SOCKETSYNC" { clients }array event_send repeat ; : addserver[ sock:socket -- ] serversarray @ not if 0 array_make serversarray ! then { serversarray @ socket @ }array serversarray ! { serversarray @ foreach swap pop dup sockcheck -1 = if pop then repeat }array serversarray ! prog getpids foreach swap pop "SOCKETSYNC" { servers clients }array event_send repeat ; : addclient[ sock:socket -- ] clientsarray @ not if 0 array_make clientsarray ! then { clientsarray @ socket @ }array clientsarray ! { clientsarray @ foreach swap pop dup sockcheck -1 = if pop then repeat }array clientsarray ! prog getpids foreach swap pop "SOCKETSYNC" { servers clients }array event_send repeat ; $def tostack array_vals pop $pubdef tostack array_vals pop $def fromstack array_make $pubdef fromstack array_make $libdef array2string : array2string[ arr:stack -- str:string ] var item { stack @ foreach item ! pop item @ case dbref? when { "d:" item @ }cat end int? when { "i:" item @ }cat end float? when { "f:" item @ }cat end string? when { "s:" item @ }cat end endcase repeat }array 1 itoc array_join ; PUBLIC array2string $libdef string2array : string2array[ str:string -- arr:stack ] var item { string @ 1 itoc explode_array foreach item ! pop item @ case "d:*" smatch when item @ "" "d:#" subst atoi dbref end "i:*" smatch when item @ "" "i:" subst atoi end "f:*" smatch when item @ "" "f:" subst strtof end "s:*" smatch when item @ 2 strcut swap pop end endcase repeat }array ; PUBLIC string2array $libdef clearsock : clearsock[ sock:socket -- ? ] prog { "/~socket/" socket @ sockdescr "/" }cat remove_prop socket @ sockclose pop ; PUBLIC clearsock $libdef readsockEx : readsockEx[ sock:socket -- str:some_data_or_other ] 2 "readsockEx" timer_start { "TIMER.readsockEx" "SOCKET.READ." socket @ sockdescr intostr strcat }array event_waitfor swap pop case ( As soon as I get some data, give it to me damnit ) "SOCKET.READ*" smatch when socket @ nbsockrecv swap not if pop socket @ closesock "" then end ( We've waited long enough for the data, YOU LOSE ) "TIMER.readsockEx" smatch when "" end endcase ; : writesockEx[ sock:socket str:text -- ] socket @ text @ socksend not if socket @ clearsock then ; $def readsock socket @ readsockEx $pubdef readsock socket @ readsockEx $def writesock socket @ swap writesockEx $pubdef writesock socket @ swap writesockEx $libdef getsock : getsock[ sock:socket string:prop -- ? ] prog { "/~socket/" socket @ sockdescr "/" prop @ }cat getprop ; PUBLIC getsock $libdef setsock : setsock[ sock:socket string:prop value -- ? ] prog { "/~socket/" socket @ sockdescr "/" prop @ }cat value @ setprop ; PUBLIC setsock $libdef getdns : getdns[ str:muckname string:prop -- ? ] prog { "/~dns/" muckname @ "/" prop @ }cat getprop ; PUBLIC getdns : decrypter[ sock:socket str:text -- str:result str:error ] var ltoken var rtoken socket @ "token" getsock dup ltoken ! not if "" -1 then text @ base64decode ltoken @ strdecrypt base64decode 8 strcut swap rtoken ! 1 strcut swap pop ltoken @ rtoken @ strcmp not if 0 else 1 then ; PUBLIC decrypter : encrypter[ sock:socket str:text -- str:result ] var token socket @ "token" getsock dup token ! not if text @ exit then { token @ " " text @ }cat base64encode token @ strencrypt base64encode ; PUBLIC encrypter $libdef netmsg : netmsg[ sock:socket int:msg -- ] msg @ case 103 = when socket @ "103 Connection refused" socksend end 104 = when socket @ "104 Connection timed out" socksend end 105 = when socket @ "105 Remote server is not a proto.net dispatcher" socksend end 200 = when socket @ "200 OK" socksend end 201 = when socket @ { "201 " socket @ "token" getsock }cat socksend end 202 = when socket @ { "202 " socket @ "rstack" getsock }cat socksend end 203 = when socket @ { "203 " prog "@muckname" getprop }cat socksend end 210 = when socket @ "210 Authentication successful." socksend end 220 = when socket @ { "220 " VERSION }cat socksend end 221 = when socket @ { "221 Hello, " socket @ "name" getsock "@" socket @ "muck" getsock ", nice to meet you." }cat socksend end 299 = when socket @ "299 Goodbye" socksend end 300 = when socket @ "300 System AUTH required" socksend end 301 = when socket @ "301 User AUTH required" socksend end 402 = when socket @ "402 Host access denied " socksend end 403 = when socket @ "403 User access denied" socksend end 404 = when socket @ "404 Service not found or unsupported" socksend end 500 = when socket @ { "500 Error in calling program: " socket @ "name" getsock }cat socksend end 501 = when socket @ "501 Malformed authentication token" socksend end 502 = when socket @ "502 Function not found in service" socksend end 503 = when socket @ "503 Malformed stack" socksend end 510 = when socket @ "510 Token required, please HELO" socksend end 511 = when socket @ "511 Invalid token" socksend end 553 = when socket @ "553 Cannot broadcast anything but a datagram" socksend end 599 = when socket @ "599 Bad command" socksend end 601 = when socket @ "601 I am not a server" socksend end 602 = when socket @ "602 I am not a client" socksend end 699 = when socket @ "699 No help available" socksend end 700 = when socket @ "700 Datagram received" socksend end 701 = when socket @ "701 Malformed datagram" socksend end 702 = when socket @ "702 Malformed call" socksend end default socket @ swap intostr " Unknown event" strcat socksend end endcase not if socket @ clearsock then ; PUBLIC netmsg : neterr[ int:num -- str:result ] num @ case 10004 = when "Navigation canceled" end 10009 = when "Invalid socket handle" end 10024 = when "Out of sockets" end 10035 = when "Socket not ready" end 10036 = when "Function already in progress" end 10037 = when "Function already complete" end 10038 = when "Non-socket datatype" end 10039 = when "Destination MUCK required" end 10040 = when "Malformed datagram" end 10041 = when "Unsupported network function in valid network program" end 10042 = when "Unsupported network program" end 10043 = when "Unsupported protocol" end 10045 = when "Remote program error" end 10050 = when "The network is down" end 10051 = when "The network is unreachable" end 10053 = when "Connection aborted" end 10054 = when "Connection reset by peer" end 10056 = when "Socket already connected" end 10057 = when "Socket not connected" end 10058 = when "Socket has been shit down" end 10060 = when "Connection timed out" end 10061 = when "Connection refused" end 10080 = when "Token required" end 10081 = when "Token is invalid" end 11001 = when "Host not found (authorative)" end 11002 = when "Host not found (non-authorative)" end 11111 = when "Unknown error" end endcase ; PUBLIC neterr $libdef muck2addr : muck2addr[ str:muckname -- str:addr int:port ] muckname @ "port" getdns if muckname @ "addr" getdns muckname @ "port" getdns else "" 0 then ; PUBLIC muck2addr $libdef dns : dns[ str:query -- str:canon-name str:ip ] var socket prog "@dns" getprop prog "@dnsp" getprop toint sockopen pop socket ! 1 3 1 for pop socket @ sockcheck 0 > if break then repeat socket @ sockcheck 0 <= if "Connection refused" "" socket @ sockclose exit then query @ writesock pop 1 sleep socket @ sockcheck 0 <= if "" "" socket @ sockclose exit then readsock readsock socket @ closesock ; PUBLIC dns $libdef p2pdgram : p2pdgram[ arr:stack str:muck str:progfunc -- int:error ] var addr var port var socket var result muck @ muck2addr port ! addr ! port @ if addr @ port @ sockopen "noerr" smatch if socket ! readsock "220 Proto.NET*" smatch if { "DGRM " progfunc @ " " stack @ array2string }cat writesock readsock dup result ! msgnum case 700 = when PNSNOERROR end 701 = when PNSEBADDGRAM end default pop 0 array_make PNSEUNKNOWN end endcase else 0 array_make PNSEPROTONOSUPPORT then else 0 array_make PNSECONNREFUSED then else 0 array_make PNSHOST_NOT_FOUND then socket @ if "QUIT" writesock socket @ closesock then ; PUBLIC p2pdgram $libdef p2prpc : p2prpc[ arr:stack str:muck str:progfunc -- arr:rstack int:error ] var addr var port var socket var result muck @ muck2addr port ! addr ! port @ if addr @ port @ sockopen "noerr" smatch if socket ! readsock "220 Proto.NET*" smatch if { "CALL " progfunc @ " " stack @ array2string }cat writesock readsock dup result ! msgnum case 202 = when result @ 4 strcut swap pop string2array tostack PNSNOERROR end 404 = when 0 array_make PNSENOHANDLER end 500 = when 0 array_make PNSEREMOTEERR end 502 = when 0 array_make PNSEBADCALL end default pop 0 array_make PNSEUNKNOWN end endcase else 0 array_make PNSEPROTONOSUPPORT then else 0 array_make PNSECONNREFUSED then else 0 array_make PNSHOST_NOT_FOUND then socket @ if "QUIT" writesock socket @ closesock then ; PUBLIC p2prpc $libdef p2pencrpc : p2pencrpc[ arr:stack str:muck str:progfunc -- arr:rstack ] var addr var port var socket var result muck @ muck2addr port ! addr ! port @ if addr @ port @ sockopen "noerr" smatch if socket ! readsock "220 Proto.NET*" smatch if { "HELO " me @ name "@" prog "@muckname" getprop }cat writesock readsock pop socket @ "token" readsock "" "201 " subst setsock { "ECAL " socket @ { progfunc @ " " stack @ array2string }cat encrypter }cat writesock readsock dup result ! msgnum case 202 = when result @ 4 strcut swap pop socket @ swap decrypter dup not if pop string2array tostack PNSNOERROR else 0 < if 0 array_make PNSETOKENREQD else 0 array_make PNSETOKENINVALID then then end 404 = when 0 array_make PNSENOHANDLER end 500 = smatch when 0 array_make PNSEREMOTEERR end 502 = smatch when 0 array_make PNSEBADCALL end 510 = smatch when 0 array_make PNSETOKENREQD end 511 = smatch when 0 array_make PNSETOKENINVALID end default pop 0 array_make PNSEUNKNOWN end endcase else 0 array_make PNSEPROTONOSUPPORT then else 0 array_make PNSECONNREFUSED then else 0 array_make PNSHOST_NOT_FOUND then socket @ if "QUIT" writesock socket @ closesock then ; PUBLIC p2pencrpc $libdef dgram : dgram[ arr:stack str:muck str:progfunc -- int:error ] var addr var port var socket var result muck @ muck2addr port ! addr ! port @ if addr @ port @ sockopen "noerr" smatch if socket ! readsock "220 Proto.NET*" smatch if { "DGRM " progfunc @ " " stack @ array2string }cat writesock readsock dup result ! msgnum case 700 = when PNSNOERROR end 701 = when PNSEBADDGRAM end default pop 0 array_make PNSEUNKNOWN end endcase else 0 array_make PNSEPROTONOSUPPORT then else 0 array_make PNSECONNREFUSED then else 0 array_make PNSHOST_NOT_FOUND then socket @ if "QUIT" writesock socket @ closesock then ; PUBLIC dgram $libdef rpc : rpc[ arr:stack str:muck str:progfunc -- arr:rstack int:error ] var addr var port var socket var result muck @ muck2addr port ! addr ! port @ if addr @ port @ sockopen "noerr" smatch if socket ! readsock "220 Proto.NET*" smatch if { "CALL " progfunc @ " " stack @ array2string }cat writesock readsock dup result ! msgnum case 202 = when result @ 4 strcut swap pop string2array tostack PNSNOERROR end 404 = when 0 array_make PNSENOHANDLER end 500 = when 0 array_make PNSEREMOTEERR end 502 = when 0 array_make PNSEBADCALL end default pop 0 array_make PNSEUNKNOWN end endcase else 0 array_make PNSEPROTONOSUPPORT then else 0 array_make PNSECONNREFUSED then else 0 array_make PNSHOST_NOT_FOUND then socket @ if "QUIT" writesock socket @ closesock then ; PUBLIC rpc $libdef enc-rpc : enc-rpc[ arr:stack str:muck str:progfunc -- arr:rstack ] var addr var port var socket var result muck @ muck2addr port ! addr ! port @ if addr @ port @ sockopen "noerr" smatch if socket ! readsock "220 Proto.NET*" smatch if { "HELO " me @ name "@" prog "@muckname" getprop }cat writesock readsock pop socket @ "token" readsock "" "201 " subst setsock { "ECAL " socket @ { progfunc @ " " stack @ array2string }cat encrypter }cat writesock readsock dup result ! msgnum case 202 = when result @ 4 strcut swap pop socket @ swap decrypter dup not if pop string2array tostack PNSNOERROR else 0 < if 0 array_make PNSETOKENREQD else 0 array_make PNSETOKENINVALID then then end 404 = when 0 array_make PNSENOHANDLER end 500 = smatch when 0 array_make PNSEREMOTEERR end 502 = smatch when 0 array_make PNSEBADCALL end 510 = smatch when 0 array_make PNSETOKENREQD end 511 = smatch when 0 array_make PNSETOKENINVALID end default pop 0 array_make PNSEUNKNOWN end endcase else 0 array_make PNSEPROTONOSUPPORT then else 0 array_make PNSECONNREFUSED then else 0 array_make PNSHOST_NOT_FOUND then socket @ if "QUIT" writesock socket @ closesock then ; PUBLIC enc-rpc $libdef auth-rpc : auth-rpc[ arr:stack str:muck str:progfunc str:username str:passwd -- arr:rstack ] ; PUBLIC auth-rpc $libdef bcast : bcast[ arr:stack str:progfunc -- ] server? if clients @ foreach servers @ fore ; PUBLIC bcast : net.help[ str:arg sock:socket -- ] "250 HELP" writesock " This help" writesock "250 HELO " writesock " Register your MUCK into this server." writesock "250 CALL " writesock " Call the function net. in on MUCK , with the indicated ," writesock " which returns a stack to the sender." writesock "250 DGRM " writesock " Like a CALL but never returns anything and exits immediately." writesock "250 BCST " writesock " Like a DGRM but calls all known MUCKs, never returns anything and exits immediately." writesock "250 QUIT" writesock " Disconnect this session" writesock ; PUBLIC net.help : net.bcst[ str:arg sock:socket -- ] var muckname var cmd var params var rsocket server? not if socket @ 601 netmsg exit then clients @ foreach swap pop { "DGRM " params @ }cat writesockEx repeat socket @ "type" getsock "CLIENT" smatch if servers @ foreach swap pop { "BCST " params @ }cat writesockEx repeat then ; : net.sync[ -- ] var muckname var muckname2 prog "/~dns/" array_get_propdirs foreach muckname ! muckname @ "server" getdns if 0 array_make muckname @ ".net:sync.dns" rpc dup if foreach swap pop ":" explode pop muckname2 ! prog { "/~dns/" muckname2 @ "/addr" }join rot setprop prog { "/~dns/" muckname2 @ "/port" }join rot setprop prog { "/~dns/" muckname2 @ "/server" }join rot setprop repeat then then repeat ; PUBLIC net.sync : net.call[ str:arg sock:socket -- ] var object var function var stack arg @ " " split stack ! ":" split function ! "$net/" swap strcat resolve object ! object @ int 0 < if socket @ 404 netmsg exit then object @ program? not if socket @ 404 netmsg exit then object @ ".net." function @ strcat cancall? not if socket @ 502 netmsg exit then stack @ string2array tostack socket @ "name" getsock dup not if pop "" then socket @ "muck" getsock dup not if pop "" then socket @ "host" getsock dup not if pop "" then socket @ "hostname" getsock dup not if pop "" then socket @ "port" getsock socket @ "token" getsock dup not if pop "" then depth try object @ ".net." function @ strcat call catch socket @ "muferror" rot setsock socket @ 500 netmsg exit endcatch depth array_make array2string socket @ "rstack" rot setsock socket @ 202 netmsg ; PUBLIC net.call : net.ecal[ str:arg sock:socket -- ] var object var function var stack socket @ arg @ decrypter case -1 = when socket @ 510 netmsg exit end 1 = when socket @ 511 netmsg exit end endcase arg ! arg @ " " split stack ! ":" split function ! "$net/" swap strcat resolve object ! object @ int 0 < if socket @ 404 netmsg exit then object @ program? not if socket @ 404 netmsg exit then object @ ".net." function @ strcat cancall? not if socket @ 502 netmsg exit then stack @ string2array tostack socket @ "name" getsock dup not if pop "" then socket @ "muck" getsock dup not if pop "" then socket @ "host" getsock dup not if pop "" then socket @ "hostname" getsock dup not if pop "" then socket @ "port" getsock socket @ "token" getsock dup not if pop "" then depth try object @ ".net." function @ strcat call catch socket @ "muferror" rot setsock socket @ 500 netmsg exit endcatch depth array_make array2string socket @ "rstack" rot socket @ swap encrypter setsock socket @ 202 netmsg ; PUBLIC net.ecal : net.ping[ str:arg sock:socket -- ] { "269 PONG " systime_precise dup arg @ strtof - " " swap }cat writesock ; PUBLIC net.ping : net.dgrm[ str:arg sock:socket -- ] var object var function var stack arg @ " " split stack ! ":" split function ! "$net/" swap strcat resolve object ! object @ int 0 < if socket @ 404 netmsg exit then object @ program? not if socket @ 404 netmsg exit then object @ ".net." function @ strcat cancall? not if socket @ 502 netmsg exit then stack @ string2array tostack socket @ "name" getsock dup not if pop "" then socket @ "muck" getsock dup not if pop "" then socket @ "host" getsock dup not if pop "" then socket @ "hostname" getsock dup not if pop "" then socket @ "port" getsock socket @ "token" getsock dup not if pop "" then depth try object @ ".net." function @ strcat call catch pop endcatch depth popn socket @ 700 netmsg socket @ clearsock ; PUBLIC net.dgrm : net.quit[ str:arg sock:socket -- ] socket @ 299 netmsg socket @ clearsock ; PUBLIC net.quit : net.helo[ str:arg sock:socket -- ] socket @ "name" arg @ "@" split pop setsock socket @ "target" #-1 setsock socket @ "muck" arg @ "@" split swap pop setsock socket @ "token" "00000000" random itoh strcat dup strlen 8 - strcut swap pop setsock socket @ 221 netmsg 0 sleep socket @ 201 netmsg ; PUBLIC net.helo : net.auth[ str:arg sock:socket -- ] var username var password var target socket @ arg @ decrypter " " split password ! username ! username @ resolve dup target ! int 0 < if socket @ 403 netmsg then target @ password @ checkpassword not if socket @ 403 netmsg else socket @ "target" target @ setsock socket @ 221 netmsg then ; PUBLIC net.auth : handler[ str:arg sock:socket -- ? ] var cmd var arg ( Set the basic socket info ) socket @ "hostname" socket @ get_sockinfo "hostname" [] setsock socket @ "host" socket @ get_sockinfo "host" [] setsock socket @ "port" socket @ get_sockinfo "port" [] setsock begin event_wait swap pop "SOCKET.READ*" smatch if socket @ nbsockrecv swap not if socket @ clearsock pid kill then depth try " " split arg ! cmd ! prog "net." cmd @ tolower strcat cancall? if arg @ socket @ prog "net." cmd @ tolower strcat call else socket @ 599 netmsg then catch dup "911 net." cmd @ tolower strcat ": " strcat swap strcat writesock socket @ clearsock "net." cmd @ tolower strcat ": " strcat swap strcat logwall endcatch then repeat ; : dispatcher var socket var eventarg var event var tmpsock begin event_wait event ! eventarg ! event @ "SOCKET.LISTEN*" smatch if eventarg @ socket ! socket @ ssl_sockaccept tmpsock ! fork not if tmpsock @ HOMEINSTANCE set_sockopt pop prog { "/~socket/" tmpsock @ sockdescr "/" }cat remove_prop tmpsock @ 220 netmsg tmpsock @ handler then then repeat ; : net.connect var cur var socket var slist prog @ "@servers" getpropstr " " explode_array slist ! slist @ foreach cur ! pop cur @ muck2addr sockopen "noerr" smatch if socket ! { "Connected to " cur @ }cat logwall readsock pop server? if { "SRVR " prog "@muckname" getprop }cat writesock else { "CLNT " prog "@muckname" getprop }cat writesock then socket @ "token" readsock "" "201 " subst setsock { "AUTH " prog "@username/" cur @ strcat getprop " " prog "@password/" cur @ strcat getprop }cat writesock readsock msgnum case 403 = when { "Authenticated FAILED to " cur @ }cat logwall socket @ sockclose end 210 = when { "Authenticated to " cur @ }cat logwall server? if socket @ addserver else socket @ serversarray ! exit then end endcase else pop { "Connection FAILED to " cur @ }cat logwall then repeat ; : startup-sequence ( net.connect ) 20 prog "@listenport" getprop lsockopen pop listener ! prog "@synctime" getprop toint "NET.SYNC" timer_start dispatcher ; : netreg ; : main ( This is the Proto.net Central Server ) param ! prog "@init" getprop not if prog "@listenport" 8472 setprop prog "@server" "1" setprop prog "@dns" "127.0.0.1" setprop prog "@dnsp" 8853 setprop prog "@pingtime" 60 setprop prog "@synctime" 15 setprop #0 "_reg/net/.net" prog setprop prog "@init" 1 setprop then command @ case "@netreg" smatch when netreg end default param @ "Startup" smatch if startup-sequence then end endcase ; . c q