1%:- if(( ( \+ ((current_prolog_flag(logicmoo_include,Call),Call))) )).
    2%:- module(mud_telnet,[]).
    3
    4:- export((
    5         prolog_tnet_server/2,
    6         setup_streams/2,
    7         player_connect_menu/4,
    8         look_brief/1,
    9         cmdShowRoomGrid/1,
   10         get_session_id_local/1,
   11         inst_label/2,
   12         display_grid_labels/0,
   13         telnet_repl_writer/4,
   14         telnet_repl_obj_to_string/3,
   15         start_mud_telnet/0,
   16         start_mud_telnet/1,         
   17         run_session/0,
   18         run_session/2,
   19         login_and_run/0,
   20         login_and_run/2,
   21         session_loop/2,
   22         get_session_io/2,
   23         kill_naughty_threads/0,
   24         set_player_telnet_options/1,
   25         register_player_stream_local/3,
   26         fmtevent/2,
   27         login_and_run_nodbg/0,
   28         login_and_run_debug/0,
   29         login_and_run_xhtml/0,
   30         telnet_restore/0
   31      )).   32
   33% Initial Telnet/Text console
   34% ALL telnet client business logic is here (removed from everywhere else!)
   35%
   36% Logicmoo Project PrologMUD: A MUD server written in Prolog
   37% Maintainer: Douglas Miles
   38% Dec 13, 2035
   39%
   40:- include(prologmud(mud_header)).   41
   42:- use_module(mud_http_hmud).   43%:- kb_shared(get_session_id/1).
   44
   45 
   46:- dynamic((lmcache:agent_session/2,
   47      lmcache:session_agent/2,
   48      lmcache:session_io/4,
   49      lmcache:agent_session/2,
   50      lmcache:session_agent/2,
   51      lmcache:session_io/4)).   52
   53:- volatile((lmcache:agent_session/2,
   54      lmcache:session_agent/2,
   55      lmcache:session_io/4,
   56      lmcache:agent_session/2,
   57      lmcache:session_agent/2,
   58      lmcache:session_io/4)).   59
   60:- ain(mtProlog(mud_telnet)).   61% UNDO % :- add_import_module(mud_telnet,world,end).
   62
   63% learnLaterWhenToCallProceedure(What):- ... code ...
   64
   65%:-ain(learnLaterWhenToCallProceedure(kill_naughty_threads)).
   66
   67%:-ain(unimpledTODO(learnLaterWhenToCallProceedure)).
   68%:-ain(unimpledTODO(codeWithTODONextToIt)).
   69
   70% instanceRecognizedBy(codeWithTODONextToIt,grovelSourceCodeLookingForComment).
   71
   72
   73
   74kill_naughty_threads:-forall(thread_property(_,alias(ID)),sanify_thread(ID)).
   75% ignore main thread
   76sanify_thread(main):-!.
   77sanify_thread(ID):- ( \+ atom_concat('httpd',_,ID)),!,
   78   ignore(( thread_statistics(ID,local,Size),MSize is 200 * 1024, Size>MSize, dmsg(big_thread(ID,local,Size)))).
   79sanify_thread(ID):-
   80   ignore(( thread_statistics(ID,local,Size),MSize is 200 * 1024, Size>MSize,
   81     % thread_signal(ID,abort) maybe
   82     dmsg(killing_big_thread(ID,local,Size)), thread_exit(ID) )).
   83
   84
   85:- meta_predicate show_room_grid_single(*,*,0).   86
   87% :- include(prologmud(mud_header)).
   88
   89% :- disable_mpreds_in_current_file.
   90
   91% :- register_module_type (utility).
   92
   93% :-  use_module(library(threadutil)).
   94
   95% ===========================================================
   96% TELNET REPL + READER
   97% ===========================================================
   98start_mud_telnet :-  app_argv1('--nonet'),!.
   99start_mud_telnet:-
  100  logicmoo_base_port(Base),
  101   WebPort is Base, % + 1000,
  102  whenever(run_network,start_mud_telnet(WebPort)).
  103
  104
  105
  106start_mud_telnet(Port):-      
  107      start_tnet(login_and_run_nodbg , Port  , "MUD Server"),
  108      start_tnet(login_and_run_debug,  Port+1  , "MUD Debug"),
  109      start_tnet(login_and_run_xhtml,  Port+2  , "MUDLET Telnet"),
  110      start_tnet(               repl,  Port+3  , "WAM-CL Telnet"),
  111      start_tnet(             prolog,  Port+23 , "PROLOG Telnet").
  112
  113golorpish:- nodebugx(golorp).
  114
  115:- dynamic(lmcache:main_thread_error_stream/1).  116:- volatile(lmcache:main_thread_error_stream/1).  117
  118save_error_stream:- lmcache:main_thread_error_stream(_),!.
  119save_error_stream:- ignore((thread_self_main,(quintus:current_stream(2, write, Err),asserta(lmcache:main_thread_error_stream(Err))))).
  120:- initialization(save_error_stream,restore).  121:- save_error_stream.  122
  123get_main_thread_error_stream(ES):-lmcache:main_thread_error_stream(ES),!.
  124get_main_thread_error_stream(main_error).
  125
  126get_session_io(In,Out):-
  127  get_session_id_local(O),
  128  thread_self(Id),
  129  lmcache:session_io(O,In,Out,Id),!.
  130
  131get_session_io(In,Out):-
  132  must(get_session_id_local(O)),
  133  thread_self(Id),
  134  current_input(In),
  135  current_output(Out),
  136  asserta(lmcache:session_io(O,In,Out,Id)),!.
  137
  138:- set_prolog_flag(debug_threads,false).  139:- set_prolog_flag(debug_threads,true).  140
  141login_and_run_xhtml :- login_and_run.
  142%login_and_run_xhtml :- login_and_run_debug.
  143
  144% login_and_run_nodbg:- current_prolog_flag(debug_threads,true),!,login_and_run.
  145login_and_run_nodbg:- 
  146   nodebugx(login_and_run),!.
  147
  148login_and_run_debug:- \+ getenv('DISPLAY',_),login_and_run.
  149login_and_run_debug:- 
  150   thread_self(Self),
  151   tdebug(Self),% debug, % guitracer,
  152   % fav_debug,!,
  153   must_det(login_and_run),!.
  154
  155get_session_id_local(O):- must(get_session_id(O)),!.
  156
  157
  158ensure_player_attached(In,Out,P):-
  159  call_u((
  160    current_agent(P)->true;player_connect_menu(In,Out,_,P))).
  161
  162player_connect_menu(In,Out,Wants,P):-
  163 setup_call_cleanup(set_local_modules(baseKB,Undo),
  164  must_det((   
  165   get_session_id_local(O),
  166   format('~N~nHello session ~q!~n',[O]),
  167   foc_current_agent(Wants),
  168   % must((foc_current_agent(P),sanity(nonvar(P)))),
  169   must((foc_current_agent(P),nonvar(P))),
  170   ain(isa(P,tHumanControlled)),
  171   register_player_stream_local(P,In,Out),
  172   format('~N~nWelcome to the MUD ~w!~n',[P]),
  173   format(Out,'~N~nThe stream ~w!~n',[Out]),
  174   colormsg([blink,fg(red)],"this is blinking red!"),!)),Undo),!.
  175
  176login_and_run_html:-
  177  login_and_run.
  178
  179login_and_run:-
  180   get_session_io(In,Out),!,
  181   login_and_run(In,Out).
  182
  183set_player_telnet_options(P):-
  184     ain(repl_writer(P,telnet_repl_writer)),
  185     ain(repl_to_string(P,telnet_repl_obj_to_string)),
  186   get_session_id_local(O),
  187   asserta(t_l:telnet_prefix(O,[P,wants,to])).
  188
  189unset_player_telnet_options(P):-
  190     get_session_id_local(O),
  191     retractall(t_l:telnet_prefix(O,[P,wants,to])),
  192     clr(repl_writer(P,_)),
  193     clr(repl_to_string(P,_)).
  194
  195goodbye_player:-
  196     call_u(foc_current_agent(P3)),
  197     deliver_event(P3,goodBye(P3)).
  198
  199run_session:-
  200   get_session_io(In,Out),
  201   run_session(In,Out).
  202
  203login_and_run(In,Out):-
  204  player_connect_menu(In,Out,_,_),!,
  205  run_session(In,Out).
  206
  207set_local_modules(BaseKB,Undo):-
  208  '$current_typein_module'(WasTM),'$current_source_module'(WasSM),
  209  fileAssertMt(WasFileMt),
  210  module(BaseKB),'$set_typein_module'(BaseKB),'$set_source_module'(BaseKB),  
  211  set_fileAssertMt(BaseKB),!,
  212  Undo = (set_fileAssertMt(WasFileMt),'$set_typein_module'(WasTM),'$set_source_module'(WasSM)),!.
  213  % set_defaultAssertMt(BaseKB),
  214  
  215
  216run_session(In,Out):-
  217 setup_call_cleanup(set_local_modules(baseKB,Undo),
  218  must_det((((     
  219     get_session_id_local(O),
  220     ensure_player_attached(In,Out,P),
  221     call(retractall,lmcache:wants_logout(O)))),!,
  222     register_player_stream_local(P,In,Out),
  223     call_u((repeat,
  224         once(session_loop(In,Out)),
  225         call(retract,lmcache:wants_logout(O)))),!,
  226      % this leaves the session
  227      call(retractall,lmcache:wants_logout(O)),
  228      ignore(current_agent(Agnt)->true;Agnt=P),
  229      deregister_player_stream_local(Agnt,In,Out))),Undo).
  230
  231
  232session_loop(In,Out):-
  233  must_det((((
  234  get_session_id_local(O),
  235  ensure_player_attached(In,Out,P),
  236  call_u(start_agent_action_thread),
  237  ignore(look_brief(P)),!,
  238  (t_l:telnet_prefix(O,Prefix)->(sformat(Prompt,'~w ~w>',[P,Prefix]));sformat(Prompt,'~w> ',[P])),
  239  prompt_read_telnet(In,Out,Prompt,List),!,
  240  enqueue_session_action(P,List,O))))).
  241
  242
  243:-export(register_player_stream_local/3).  244register_player_stream_local(P,In,Out):-
  245  must_det((((
  246   set_player_telnet_options(P),
  247   get_session_id_local(O),thread_self(Id),
  248   retractall(lmcache:session_io(_,_,_,Id)),
  249   retractall(lmcache:session_io(O,_,_,_)),
  250   asserta_new(lmcache:session_io(O,In,Out,Id)),
  251  %  wdmsg(asserta_new(lmcache:session_io(O,In,Out,Id))),
  252   retractall(lmcache:session_agent(O,_)),
  253   asserta_new(lmcache:session_agent(O,P)),
  254   retractall(lmcache:agent_session(_,O)),
  255   asserta_new(lmcache:agent_session(P,O)),
  256   nop(check_console(Id,In,Out,_Err)))))).
  257
  258deregister_player_stream_local(P,In,Out):-
  259  must_det((((
  260   unset_player_telnet_options(P),
  261   get_session_id_local(O),thread_self(Id),
  262   retractall(lmcache:session_io(_,_,_,Id)),
  263   retractall(lmcache:session_io(O,_,_,_)),
  264   %  wdmsg(asserta_new(lmcache:session_io(O,In,Out,Id))),
  265   retractall(lmcache:session_agent(O,_)),
  266   retractall(lmcache:agent_session(_,O)),
  267   nop(check_console(Id,In,Out,_Err)))))).
  268
  269check_console(Id,In,Out,Err):-
  270    (thread_self_main->get_main_thread_error_stream(Err); Err=Out),
  271     (call(call,thread_util:has_console(Id,In, Out,Err))->true;
  272       ((call(retractall,thread_util:has_console(Id,_,_,_)),
  273          call(asserta,thread_util:has_console(Id,In,Out,Err))))).
  274
  275
  276:-export(enqueue_session_action/3).  277
  278enqueue_session_action(_A,[+, Text],_S):- string(Text), must(if_defined(assert_text(tWorld,Text))).
  279%enqueue_session_action(A,[W0,W1|WL],S):- string(Text),!,enqueue_session_action(A,[actSay,[W0,W1|WL]],S).
  280enqueue_session_action(A,L,S):- show_call(must(call_u(enqueue_agent_action(A,L,S)))),!.
  281
  282setup_streams:-
  283  get_session_io(In,Out),
  284  setup_streams(In, Out),
  285  call(listing,thread_util:has_console/4).
  286
  287setup_streams(In,Out):- var(In),!,current_input(In),setup_streams(In,Out).
  288setup_streams(In,Out):- var(Out),!,current_output(Out),setup_streams(In,Out).
  289setup_streams(In,Out):- thread_self(Id),
  290   thread_setup_streams(Id,In,Out).
  291
  292thread_setup_streams(Id,In,Out):- memberchk(Id,[0,main]),thread_self_main,!,
  293   stream_property(Err,file_no(2)),
  294   call(retractall,thread_util:has_console(Id, _, _, _)),
  295   thread_at_exit(call(retractall,thread_util:has_console(Id, _, _, _))),
  296   call(asserta,thread_util:has_console(Id, In, Out, Err)),!.
  297thread_setup_streams(Id,In,Out):- 
  298   set_prolog_IO(In, Out, Out), thread_setup_streams(Id,In,Out,user_error).
  299
  300thread_setup_streams(Id,In,Out,Err):-
  301 must_det_l((
  302   set_prolog_flag(color_term,true),
  303   set_prolog_flag(tty_control, true),   
  304   setup_stream_props(current_input,In),
  305   setup_stream_props(current_ouput,Out),   
  306   setup_error_stream(Id,Err))).
  307
  308setup_stream_props(Name,Stream):-  
  309 must_det_l((
  310   set_stream_ice(Stream, close_on_exec(false)),
  311   set_stream_ice(Stream, close_on_abort(false)),
  312   %set_stream_ice(Stream, alias(Name)),
  313   current_prolog_flag(encoding, Enc),set_stream_ice(Stream, encoding(Enc)),
  314   set_stream_ice(Stream, type(text)),
  315   %stream_property(Stream,mode(_Dir)),
  316   %set_stream_ice(Stream, type(text)),
  317   %set_stream_ice(Stream, representation_errors(warn)),
  318   %set_stream_ice(Stream, write_errors(warn)),   
  319   %set_stream_ice(Stream, eof_action(eof_code)),
  320   %set_stream_ice(Stream, buffer_size(1)),   
  321   (input_stream(Stream)->set_stream_ice(Stream, newline(detect));true),
  322   set_stream_ice(Stream, tty(true)),
  323   nop(forall(stream_property(Stream,Prop),dmsg(stream_info(Name,Stream,Prop)))))).
  324   
  325   
  326find_err_from_out(Out,Err):-
  327 quintus:current_stream(N,write,Out),
  328 dif(Out,Err), 
  329 ((quintus:current_stream(N,write,Err),stream_property(Err,alias(user_error))) -> true ;
  330   ((quintus:current_stream(N,write,Err), \+ stream_property(Err,buffer(full)), \+ stream_property(Err,buffer(line))))).
  331
  332
  333setup_error_stream(Id,Err):-
  334  must_det_l((
  335   set_thread_error_stream(Id,Err),!,
  336   %current_prolog_flag(encoding, Enc),set_stream_ice(Err, encoding(Enc)),   
  337   %atom_concat(user_error_,Id,StreamName),set_stream_ice(Err, alias(StreamName)),
  338   %set_stream_ice(Err, alias(user_error)),
  339   set_stream_ice(Err, close_on_exec(false)),
  340   set_stream_ice(Err, close_on_abort(false)),
  341   set_stream_ice(Err, buffer(none)),
  342   set_stream_ice(Err, newline(dos)))),!.
  343
  344
  345fmtevent(Out,NewEvent):-string(NewEvent),!,format(Out,'~s',[NewEvent]).
  346fmtevent(Out,NewEvent):-format(Out,'~N~q.~n',[NewEvent]).
  347
  348:-thread_local(t_l:telnet_prefix/2).  349
  350% :-set_tty_control(true).
  351
  352:-export(prompt_read/4).  353prompt_read_telnet(In,Out,Prompt,Atom):-
  354      get_session_id_local(O),
  355      prompt_read(In,Out,Prompt,IAtom),
  356      (IAtom==end_of_file -> (call(assert,lmcache:wants_logout(O)),Atom='quit') ; IAtom=Atom),!.
  357
  358prompt_read(In,Out,Prompt,Atom):-
  359     with_output_to(Out,ansi_format([reset,hfg(white),bold],'~w',[Prompt])),flush_output(Out),
  360     repeat,read_code_list_or_next_command_with_prefix(In,Atom),!.
  361
  362local_to_words_list(Atom,Words):-var(Atom),!,Words = Atom.
  363local_to_words_list(end_of_file,end_of_file):-!.
  364local_to_words_list([],[]):-!.
  365local_to_words_list(Atom,Words):-to_word_list(Atom,Words),!.
  366
  367maybe_prepend_prefix(Words,Words).
  368
  369read_code_list_or_next_command_with_prefix(In,Words):- read_code_list_or_next_command(In,Atom),
  370  add_history(Atom),
  371  %ignore(prolog:history(In, Atom);prolog:history(user_input, Atom);thread_signal(main,ignore(prolog:history(user_input, Atom)))),
  372  show_call(local_to_words_list(Atom,WordsM)),!,maybe_prepend_prefix(WordsM,Words).
  373
  374
  375read_code_list_or_next_command(Atom):-current_input(In),read_code_list_or_next_command(In,Atom),!.
  376
  377read_code_list_or_next_command(In,end_of_file):- at_end_of_stream(In),!.
  378read_code_list_or_next_command(In,Atom):-
  379 (var(In)->current_input(In);true), catch(wait_for_input([In], Ready, 1),_,fail),!,  member(In,Ready),
  380  read_pending_input(In,CodesL,[]),!,is_list(CodesL),CodesL\==[],
  381   ((last(CodesL,EOL),member(EOL,[10,13])) -> code_list_to_next_command(CodesL,Atom);
  382    (read_line_to_codes(In,CodesR), (is_list(CodesR)-> (append(CodesL,CodesR,NewCodes),code_list_to_next_command(NewCodes,Atom)); Atom=CodesR))),!.
  383
  384read_code_list_or_next_command(In,Atom):-
  385  read_pending_input(In,CodesL,[]),is_list(CodesL),CodesL\==[],
  386   ((last(CodesL,EOL),member(EOL,[10,13])) -> code_list_to_next_command(CodesL,Atom);
  387    (read_line_to_codes(In,CodesR), (is_list(CodesR)-> (append(CodesL,CodesR,NewCodes),code_list_to_next_command(NewCodes,Atom)); Atom=CodesR))),!.
  388
  389code_list_to_next_command(end_of_file,end_of_file).
  390code_list_to_next_command(NewCodes,Atom):-append(Left,[EOL],NewCodes),EOL<33,!,code_list_to_next_command(Left,Atom).
  391code_list_to_next_command( [EOL|NewCodes],Atom):-EOL<33,!,code_list_to_next_command(NewCodes,Atom).
  392code_list_to_next_command( [],"l").
  393code_list_to_next_command( [91|REST],TERM):- on_x_fail((atom_codes(A,[91|REST]),atom_to_term(A,TERM,[]))),!.
  394code_list_to_next_command(NewCodes,Atom):-atom_codes(Atom,NewCodes),!.
  395
  396:-export(scan_src_updates/0).  397
  398tick_tock:-
  399           scan_src_updates,!,fmt('tick tock',[]),sleep(0.1),!.
  400
  401scan_src_updates:- !.
  402scan_src_updates:- ignore((thread_self_main,ignore((catch(make,E,dmsg(E)))))).
  403
  404
  405% ===========================================================
  406% DEFAULT TELNET "LOOK"
  407% ===========================================================
  408
  409telnet_repl_writer(_TL,call,ftTerm,Goal):-!,ignore(on_x_debug(Goal)).
  410telnet_repl_writer( TL,text,Type,[V]):-telnet_repl_writer(TL,text,Type,V).
  411telnet_repl_writer( TL,text,Type,V):- is_list(V),merge_elements(V,L),V\=@=L,!,telnet_repl_writer( TL,text,Type,L).
  412telnet_repl_writer(_TL,text,Type,V):-copy_term(Type,TypeO),ignore(TypeO=t),fmt('text(~q).~n',[V]).
  413telnet_repl_writer(_TL,N,Type,V):-copy_term(Type,TypeO),ignore(TypeO=t),fmt('~q=(~w)~q.~n',[N,TypeO,V]).
  414
  415telnet_repl_obj_to_string(O,_TypeHint,O):-!.
  416telnet_repl_obj_to_string(O,_TypeHint,S):- must(object_string(O,S)),!.
  417telnet_repl_obj_to_string(O,Type,toString(TypeO,O)):-copy_term(Type,TypeO),ignore(TypeO=s).
  418
  419
  420% ===========================================================
  421% DEFAULT TEXT
  422% ===========================================================
  423:- dynamic(baseKB:mudLastCommand/2).  424look_brief(Agent):- prop(Agent,mudLastCommand,X),nonvar(X),functor(X,actLook,_),!.
  425
  426look_brief(Agent):- !,call_u(look_as(Agent)),!.
  427look_brief(Agent):- \+ prop(Agent,mudNeedsLook,vTrue),!.
  428look_brief(Agent):- must(prop(Agent,mudNeedsLook,vTrue)),call_u(look_as(Agent)),!.
  429
  430merge_elements(V,V):-not(is_list((V))),!.
  431merge_elements([],[]):-!.
  432merge_elements([E],[E]):-!.
  433merge_elements(V,V).
  434% merge_elements(V,M):-list_to_set(V,[E|More]),maplist(simply_ )..
  435
  436% Display what the agent sees in a form which
  437% makes sense to me
  438
  439write_pretty([]).
  440write_pretty(Percepts) :-
  441	write_pretty_aux(Percepts, Rest, 0),!,
  442	nl,
  443	write_pretty(Rest),!.
  444
  445write_pretty_aux(Rest,Rest,5).
  446write_pretty_aux([[]|Tail],Return,Column) :-
  447	Ctemp is Column + 1,
  448	typeHasGlyph(Obj,0),
  449	write(Obj), write(' '),
  450	write_pretty_aux(Tail,Return,Ctemp).
  451write_pretty_aux([[vDark]|Tail],Return,Column) :-
  452	Ctemp is Column + 1,
  453	write('dk '),
  454	write_pretty_aux(Tail,Return,Ctemp).
  455write_pretty_aux([[Head]|Tail], Return, Column) :-
  456	Ctemp is Column + 1,
  457	typeHasGlyph(Map,Head),
  458	write(Map), write(' '),
  459	write_pretty_aux(Tail, Return, Ctemp).
  460write_pretty_aux([[Agent]|Tail],Return,Column) :-
  461	Ctemp is Column + 1,
  462	isa(Agent,tAgent),
  463	write('Ag'), write(' '),
  464	write_pretty_aux(Tail,Return,Ctemp).
  465write_pretty_aux([[_|_]|Tail],Return,Column) :-
  466	Ntemp is Column + 1,
  467	write('A+'), write(' '),
  468	write_pretty_aux(Tail,Return,Ntemp).
  469
  470
  471
  472
  473cmdShowRoomGrid(Room) :- ignore(show_room_grid_new(Room)),!.
  474% cmdShowRoomGrid(Room) :-show_room_grid_old(Room),!.
  475
  476% ===================================================================
  477% show_room_grid_new(Room)
  478% ===================================================================
  479:-export(show_room_grid_new/1).  480show_room_grid_new(Room):-
  481 call_u((
  482   grid_size(Room,Xs,Ys,_Zs),
  483   Ys1 is Ys+1,Xs1 is Xs+1,
  484   forall(between(0,Ys1,Y),
  485   ((nl,
  486   forall(between(0,Xs1,X),
  487   ((loc_to_xy(Room,X,Y,LOC),
  488   write(' '),
  489   OutsideTest = (not(between(1,Xs,X));not(between(1,Ys,Y))),
  490   once(show_room_grid_single(Room,LOC,OutsideTest)))))))))),!,nl.
  491show_room_grid_new(_):-nl.
  492
  493door_label(R,Dir,'  '):- pathBetween_call(R,Dir,SP),atomic(SP).
  494
  495asserted_atloc_for_map(O,L):-asserted_atloc(O,L),O\=apathFn(_,_).
  496asserted_atloc(O,L):-is_asserted(mudAtLoc(O,L)).
  497
  498show_room_grid_single(Room, xyzFn(Room,X,Y,Z),OutsideTest):- call_u((call(OutsideTest), doorLocation(Room,X,Y,Z,Dir),door_label(Room,Dir,Label))),write(Label),!.
  499show_room_grid_single(_Room,_LOC,OutsideTest):- call(OutsideTest),!,write('[]'),!.
  500show_room_grid_single(_Room,LOC,_OutsideTest):- asserted_atloc_for_map(Obj,LOC),inst_label(Obj,Label), write(Label), !.
  501show_room_grid_single(_Room,LOC,_OutsideTest):- asserted_atloc_for_map(_Obj,LOC),write('..'), !.
  502show_room_grid_single(_Room,_LOC,_OutsideTest):- write('--'), !.
  503
  504atom_label(SLabel,SLab2):- atom_concat('NPC0',L,SLabel),!,atom_label(L,SLab2),!.
  505atom_label(SLabel,SLab2):- atom_concat('NPC',L,SLabel),!,atom_label(L,SLab2),!.
  506atom_label(SLabel,SLab2):- once(i_name(SLabel,L)),L\=SLabel,atom_label(L,SLab2),!.
  507%atom_label(SLabel,SLab2):- sub_atom(SLabel,2,2,_,SLab2),!.
  508atom_label(SLabel,SLab2):- sub_atom(SLabel,1,2,_,SLab2),!.
  509atom_label(SLabel,SLab2):- sub_atom(SLabel,0,2,_,SLab2),!.
  510
  511inst_label(Obj,Label):-  typeHasGlyph(Obj,Label),!.
  512inst_label(Obj,SLab2):-  atom(Obj),atom_label(Obj,SLab2).
  513inst_label(Obj,SLab2):-  term_to_atom(Obj,SLabel),atom_label(SLabel,SLab2).
  514inst_label(Obj,Label):-  iprops(Obj,nameString(Val)),Val\=Obj,inst_label(Val,Label),!.
  515inst_label(Obj,Label):-  iprops(Obj,mudNamed(Val)),Val\=Obj,!,inst_label(Val,Label),!.
  516inst_label(Obj,Label):-  iprops(Obj,isa(Val)),Val\=Obj,inst_label(Val,Label),!.
  517inst_label(_Obj,'&&').
  518
  519% ===================================================================
  520% show_room_grid_old(Room)
  521% ===================================================================
  522% Display world
  523show_room_grid_old(Room) :-
  524	call_u(gridValue(Room,1,G,_)),
  525	length(G,N),
  526	M is N + 1,
  527	cmdShowRoomGrid(Room,1,1,M),!.
  528
  529cmdShowRoomGrid(Room,Old,N,N) :-
  530	New is Old + 1,
  531	\+ call_u(gridValue(Room,New,N,_)),
  532	nl,
  533	!.
  534
  535cmdShowRoomGrid(Room,Old,N,N) :-
  536	New is Old + 1,
  537	nl,
  538	!,
  539	cmdShowRoomGrid(Room,New,1,N).
  540cmdShowRoomGrid(Room,Y,X,N) :-
  541      loc_to_xy(Room,X,Y,LOC),
  542	asserted_atloc(Obj,LOC),
  543        props(Obj,isa(tAgent)),
  544	list_agents(Agents),
  545	obj_memb(Agent,Agents),
  546	asserted_atloc(Agent,LOC),
  547	write('Region1+'), write(' '),
  548	XX is X + 1,
  549	!,
  550	cmdShowRoomGrid(Room,Y,XX,N).
  551cmdShowRoomGrid(Room,Y,X,N) :-
  552        loc_to_xy(Room,X,Y,LOC),
  553	asserted_atloc(Obj,LOC),
  554        (isa(Obj,Class),
  555	typeHasGlyph(Label,Class)),!,
  556	write(Label), write(' '),
  557	XX is X + 1,
  558	!,
  559	cmdShowRoomGrid(Room,Y,XX,N).
  560cmdShowRoomGrid(Room,Y,X,N) :-
  561      loc_to_xy(Room,X,Y,LOC),
  562	asserted_atloc(Agent,LOC),
  563	isa(Agent,tAgent),!,
  564	write('Ag'), write(' '),
  565	XX is X + 1,
  566	!,
  567	cmdShowRoomGrid(Room,Y,XX,N).
  568
  569
  570% Used to display the labels of the grid locations. (the key to the map).
  571% Used at end of run.
  572display_grid_labels :-
  573	findall([Label,Name],typeHasGlyph(Name,Label),List),
  574	forall(prop_memb([Label,Name],List),
  575	           (write(Label), write('='), write(Name), write(' '))),
  576		   nl.
  577
  578
  579
  580
  581
  582
  583% :- include(prologmud(mud_footer)).
  584
  585
  586
  587:- use_module(library(socket)).
 prolog_tnet_server(?Port, +Options)
Create a TCP/IP based server on the given Port, so you can telnet into Prolog and run an interactive session. This library is intended to provide access for debugging and management of embedded servers.

Currently defined options are:

allow(IP)
Allow access from IP, a term of the format ip(A,B,C,D). Multiple of such terms can exist and access is granted if the peer IP address unifies to one of them. If no allow option is provided access is only granted from ip(127,0,0,1) (localhost).

For example:

?- prolog_tnet_server(4000, []).

% telnet localhost 4000
Welcome to the SWI-Prolog server on thread 3

1 ?-
bug
- As the connection does not involve a terminal, command history and completion are not provided. Neither are interrupts (Control-C). To terminate the Prolog shell one must enter the command "end_of_file."
  621start_tnet(Call,Port,Description):- PortNum is Port,
  622  must(prolog_tnet_server(PortNum, [allow(_),call(Call),description(Description)])),!.
  623
  624prolog_tnet_server(Port, Options):-  
  625 \+ member(alias(_),Options),
  626 option(call(Call),Options,mud_telnet),
  627 atomic_list_concat([Call,'_',Port],Alias),!, 
  628 prolog_tnet_server(Port, [alias(Alias)|Options]).
  629
  630prolog_tnet_server(_Port, Options) :- member(alias(Alias),Options),thread_property(Base, status(running)),Base==Alias,!.
  631
  632prolog_tnet_server(Port, Options) :-
  633    tcp_socket(ServerSocket),
  634    tcp_setopt(ServerSocket, reuseaddr),
  635    tcp_bind(ServerSocket, Port),
  636    tcp_listen(ServerSocket, 5),
  637    option(alias(Alias),Options,prolog_tnet_server),
  638    option(description(Desc),Options,Alias),
  639    dmsg(Port=Desc),
  640    thread_create(mud_server_loop(ServerSocket, Options), _,
  641                  [ alias(Alias)
  642                  ]),!.
  643
  644peer_to_host(Peer,Host):- catch(tcp_host_to_address(Host, Peer),_,fail),!.
  645peer_to_host(Peer,Host):- atom(Peer),Peer=Host,!.
  646peer_to_host(Peer,Host):- compound(Peer),catch((Peer=..PeerL,atomic_list_concat(PeerL,'.',Host)),_,fail),!.
  647peer_to_host(Peer,Host):- term_to_atom(Peer,Host),!.
  648
  649
  650mud_server_loop(ServerSocket, Options) :-
  651    tcp_accept(ServerSocket, ClientSock, Peer),
  652    tcp_open_socket(ClientSock, In, Out),
  653    set_stream(In, close_on_abort(false)),
  654    set_stream(Out, close_on_abort(false)),
  655    peer_to_host(Peer,Host),
  656    gensym(inst_,Num),
  657    option(alias(ServerAlias),Options,prolog_tnet_server),
  658    atomic_list_concat(['client_',Host,'_',Num, '@', ServerAlias], Alias),
  659    
  660
  661    catch(thread_create(
  662              call_service_mud_client(Host, Alias, ClientSock, In, Out, Peer, Options),
  663              _,
  664              [ alias(Alias),detached(true)
  665              ]),
  666          error(permission_error(create, thread, Alias), _),
  667          fail),
  668    !,
  669    mud_server_loop(ServerSocket, Options).
  670
  671
  672call_service_mud_client(Host, Alias, ClientSock, In, Out, Peer, Options):-
  673  call(call,service_mud_client(Host, Alias, ClientSock, In, Out, Peer, Options)).
  674
  675service_mud_client(Host,Alias,ClientSock,In,Out,Peer,Options) :-
  676    option(allow(PeerAllow),Options,ip(127,0,0,1))-> PeerAllow=Peer,
  677    !,
  678    thread_self(Id),
  679    set_prolog_flag(tty_control, true),
  680    set_prolog_IO(In, Out, Out),    
  681    set_stream(In, tty(true)),
  682    % TODO figure out how to get immedate results
  683    % set_stream(In, buffer_size(1)),
  684    set_stream(user_output, tty(true)),
  685    set_stream(user_error, tty(true)),
  686    set_thread_error_stream(Id,user_error),
  687    current_prolog_flag(encoding, Enc),
  688    set_stream(user_input, encoding(Enc)),
  689    set_stream(user_output, encoding(Enc)),
  690    set_stream(user_error, encoding(Enc)),
  691    set_stream(user_input, newline(detect)),
  692    set_stream(user_output, newline(dos)),
  693    set_stream(user_error, newline(dos)),
  694
  695    call(retractall,thread_util:has_console(Id, _, _, _)),
  696    thread_at_exit(call(retractall,thread_util:has_console(Id, _, _, _))),
  697    call(asserta,thread_util:has_console(Id, In, Out, Out)),
  698
  699    option(call(Call), Options, prolog),
  700    format(main_error,'~N~n~q~n~n',[service_mud_client_call(Call,Id,Alias,ClientSock,In,Out,Host,Peer,Options)]),
  701    format(user_error,
  702           'Welcome to the SWI-Prolog LogicMOO ~q on thread ~w~n~n',
  703           [Call,Id]),
  704    call_cleanup(Call,
  705                 ( close(In),
  706                   close(Out),
  707                   thread_detach(Id))).
  708
  709service_mud_client(Host,Alias,ClientSock,In,Out,Peer,Options):-
  710    thread_self(Id),option(call(Call), Options, prolog),
  711    format(main_error,'~N~n~q~n~n',[rejecting(Call,Id,Alias,ClientSock,In,Out,Host,Peer,Options)]),    
  712    format(Out, 'Bye!!~n', []),
  713    close(In),
  714    close(Out),
  715    thread_detach(Id).
  716
  717
  718make_client_alias(Host,Alias):- thread_self(Prefix),make_client_alias3(Prefix,Host,Alias).
  719
  720make_client_alias3(Prefix,Host,AliasH):- is_list(Host),must(atomic_list_concat([Prefix,'client'| Host], '.', AliasH)),!.
  721make_client_alias3(Prefix,Host,AliasH):- compound(Host),Host=..HostL,make_client_alias3(Prefix,HostL,AliasH).
  722make_client_alias3(Prefix,Host,AliasH):- term_to_atom(Host,AHost),must(atomic_list_concat([Prefix,'client', AHost], '_', AliasH)).
  723
  724
  725call_close_and_detatch(In, Out, Id, Call):-
  726    call_cleanup(call(Call),( close_connection(In, Out),ignore(thread_detach(Id)))).
  727
  728
  729
  730close_connection(In, Out) :-
  731        call(retractall,thread_util:has_console(_,In,Out,_)),
  732        ignore(catch(close(In, [force(true)]),_,true)),
  733        ignore(catch(close(Out, [force(true)]),_,true)).
  734
  735strm_info(Out,Name,Strm):-nl,write(Out,Name = Strm),forall(stream_property(Strm,P),'format'(Out,', ~q',[P])),nl(Out).
  736
  737
  738set_stream_ice(Stream, Alias, NV):- catch(set_stream(Alias,NV),_,catch(set_stream(Stream,NV),E,nop(dmsg(E)))).
  739set_stream_ice(Stream, NV):- catch(set_stream(Stream,NV),E,(dmsg(set_stream(Stream,NV,E)))).
  740
  741
  742
  743
  744% correct_o_stream:-current_error(E),set_stream_ice(E).
  745
  746telnet_restore :-  app_argv('--notelnet'),!.
  747telnet_restore :-
  748      % add_import_module(mud_telnet,baseKB,end),
  749      assert_if_new(( baseKB:deliver_event_hooks(A,Event):-subst(Event,reciever,you,NewEventM),subst(NewEventM,A,you,NewEvent),
  750        foreach(no_repeats(call_u(get_agent_sessions(A,O))),
  751         foreach(no_repeats(lmcache:session_io(O,_In,Out,_Id)),
  752          fmtevent(Out,NewEvent))))),
  753      must(start_mud_telnet),
  754      nop(must(golorp_start)).
  755
  756
  757:- all_source_file_predicates_are_transparent.  758:- fixup_exports.  759
  760golorp_start :- app_argv('--nogolorp'),!.
  761golorp_start:- logicmoo_base_port(Port),
  762    ensure_loaded('/opt/logicmoo_workspace/packs_xtra/logicmoo_packages/prolog/golorp/load'),
  763    start_tnet(golorpish,  Port+25 , "GOLORP Telnet").
  764
  765
  766:- initialization(telnet_restore).  767:- initialization(telnet_restore,now).  768:- initialization(telnet_restore,restore).