Jump to content

Recommended Posts

Posted

Well, since CLI experience in mangos is lacking, i thought ill drop this patch that adds readline support under linux OS, with history of commands scrolling, and tab completion of commands. Some parts of the diff are hand-written (to get rid of trinityisms) so you may have to apply it manually. Also, remember to set up automake to link against readline ;)

--- a/src/game/Chat.h
+++ b/src/game/Chat.h
@@ -73,7 +73,7 @@ class ChatHandler
        int ParseCommands(const char* text);

        virtual char const* GetName() const;
-
+        static ChatCommand* getCommandTable();
    protected:
        explicit ChatHandler() : m_session(NULL) {}      // for CLI subclass

@@ -89,8 +89,6 @@ class ChatHandler
        bool ShowHelpForCommand(ChatCommand *table, const char* cmd);
        bool ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd);

-        ChatCommand* getCommandTable();
-
        bool HandleAccountCommand(const char* args);
        bool HandleAccountCreateCommand(const char* args);
        bool HandleAccountDeleteCommand(const char* args);

--- a/src/trinitycore/CliRunnable.cpp
+++ b/src/trinitycore/CliRunnable.cpp
@@ -37,6 +37,56 @@
#include "Player.h"
#include "Chat.h"

+#if PLATFORM != WINDOWS
+#include <readline/readline.h>
+#include <readline/history.h>
+
+char * command_finder(const char* text, int state)
+{
+  static int idx,len;
+  const char* ret;
+  ChatCommand *cmd = ChatHandler::getCommandTable();
+
+  if(!state)
+    {
+      idx = 0;
+      len = strlen(text);
+    }
+
+  while(ret = cmd[idx].Name)
+    {
+      if(!cmd[idx].AllowConsole)
+    {
+    idx++;
+    continue;
+    }
+
+      idx++;
+      //printf("Checking %s \\n", cmd[idx].Name);
+      if (strncmp(ret, text, len) == 0)
+    return strdup(ret);
+      if(cmd[idx].Name == NULL)
+    break;
+    }
+
+  return ((char*)NULL);
+
+}
+
+char ** cli_completion(const char * text, int start, int end)
+{
+  char ** matches;
+  matches = (char**)NULL;
+  
+  if(start == 0)
+    matches = rl_completion_matches((char*)text,&command_finder);
+  else
+    rl_bind_key('\\t',rl_abort);
+  return (matches);
+}
+
+#endif
+
void utf8print(const char* str)
{
#if PLATFORM == PLATFORM_WINDOWS
@@ -316,10 +366,10 @@ void CliRunnable::run()
    WorldDatabase.ThreadStart();                                // let thread do safe mySQL requests

    char commandbuf[256];
-
+    bool canflush = true;
    ///- Display the list of available CLI functions then beep
    sLog.outString();
-
+    rl_attempted_completion_function = cli_completion;
    if(sConfig.GetBoolDefault("BeepAtStart", true))
        printf("\\a");                                       // \\a = Alert

@@ -331,15 +381,16 @@ void CliRunnable::run()
    while (!World::IsStopped())
    {
        fflush(stdout);
-        #ifdef linux
-        while (!kb_hit_return() && !World::IsStopped())
-            // With this, we limit CLI to 10commands/second
-            usleep(100);
-        if (World::IsStopped())
-            break;
-        #endif
-        char *command_str = fgets(commandbuf,sizeof(commandbuf),stdin);
-        if (command_str != NULL)
+
+        char *command_str ;             // = fgets(commandbuf,sizeof(commandbuf),stdin);
+
+    #if PLATFORM == WINDOWS
+    command_str = fgets(commandbuf,sizeof(commandbuf),stdin);
+    #else
+    command_str = readline("TC>");
+    rl_bind_key('\\t',rl_complete);
+    #endif
+    if (command_str != NULL)
        {
            for(int x=0;command_str[x];x++)
                if(command_str[x]=='\\r'||command_str[x]=='\\n')
@@ -351,23 +402,30 @@ void CliRunnable::run()

            if(!*command_str)
            {
-                printf("TC>");
+          #if PLATFORM == WINDOWS
+            printf("TC>");
+          #endif
                continue;
            }

            std::string command;
            if(!consoleToUtf8(command_str,command))         // convert from console encoding to utf8
            {
-                printf("TC>");
+          #if PLATFORM == WINDOWS
+            printf("TC>");
+          #endif
                continue;
            }
+        fflush(stdout);
+            sWorld.QueueCliCommand(&utf8print,command.c_str());
+                    #if PLATFORM != WINDOWS
+        add_history(command.c_str());
+                    #endif 

-            sWorld.QueueCliCommand(&utf8print,command.c_str());
-        }
+    }
        else if (feof(stdin))
        {
            World::StopNow(SHUTDOWN_EXIT_CODE);
        }
+
    }

    ///- End the database thread

[vladimir: extracted from http://getmangos.eu/community/showthread.php?p=36981#post36981 ]

  • 39 years later...
Posted

Oops. I forgot to remove the "TC>" in original diff. Hope that doesnt hurt anyone. Ncurses is nice, but history and tab completion is what i missed the most, so thats what i started with first.

Posted

Hmm, ... readline not installed at all UNIX as i understand and then will need some configure code for use only if installed.

If some one intrested in prepering in proper way to mangos this can be intrested maybe... i don't know. Not work at UNiX/Linux many last time...

Posted
Hmm, ... readline not installed at all UNIX as i understand

Yes and no, this library is used in tonnes of free software (bash, gdb, and so on...) But devel packages are still needed for building.

and then will need some configure code for use only if installed.

No, not at all. Configuration is optionall and it only overrides default behaviour.

Posted

AC_CHECK_LIB( readline, readline, [TERMLIB=-lreadline],[AC_MSG_ERROR([Missing readline])] )

... and at the end of configure.ac add

AC_SUBST(TERMLIB)

then in Makefile.am extend LDFLAGS with $( TERMLIB ).

That would allow us to use readline.

Posted
In other words, Vladimir wants something like an --enable-readline for configure.ac.

Last time i checked Vladimir could speak for himself

then in Makefile.am extend LDFLAGS with $( TERMLIB ).

That would allow us to use readline.

Thanks, i am by no means automake guy :)

Posted

We could also change the library check to e.g. check for both ncurses and readline, and use whatever is available.

Might be an idea to support both, as either readline or ncurses always is available on Linux, and at least Fedora, openSUSE, and Debian (and derivatives) always include both by default.

Posted
We could also change the library check to e.g. check for both ncurses and readline, and use whatever is available.

Might be an idea to support both, as either readline or ncurses always is available on Linux, and at least Fedora, openSUSE, and Debian (and derivatives) always include both by default.

It actually is the only idea to allow user to write and not get interrupted by log output. Question is what about windoze users?

  • 7 months later...
Posted

For build it:

make ChatHandler::SetDataForCommandInTable static.

the line

bool canflush = true;

is useless.

the line

rl_attempted_completion_function = cli_completion;

must be online for no Windows system.

Apply the changes to configure and makefile, autoreconf, and build.

So actually it's not perfect, but history is appreciable.

Posted

When I read the title of the thread I thought what the hell can this be. After that I tought "The MaNGOS command line should be modified to behave more properly". Well great work, keep it up.

Another thing that should need fixing is that the mangos> dissapears when there's other output, have you fixed this or ?

Posted

Same thought about xeross155, the mangos> disappears when there is some output and it also takes some seconds to appear after executing something. The only way to make it appear faster is to press enter twice.

  • 1 year later...
Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use