/* core/commandbuffer.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include #include #include #include "sys/sys.h" #include "core/commandbuffer.h" #include "core/func.h" #include "core/cvar.h" #include "core/gameinterface.h" namespace core { void func_list_func(std::istringstream const &args) { Func::list(); } void func_list_var(std::istringstream const &args) { Cvar::list(); } void func_list_ent(std::istringstream const &args) { Entity::list(); } std::stringstream CommandBuffer::cmdbuf(std::stringstream::in | std::stringstream::out); void CommandBuffer::init() { con_debug << "Initializing command buffer...\n"; Func::add("list_var", (FuncPtr)func_list_var); Func::add("list_func", (FuncPtr)func_list_func); Func::add("list_ent", (FuncPtr)func_list_ent); } void CommandBuffer::shutdown() { con_debug << "Shutting down command buffer...\n"; Func::remove("list_var"); Func::remove("list_func"); Func::remove("list_ent"); } void CommandBuffer::exec(std::string const &cmdline) { if (!cmdline.size()) return; std::istringstream cmdstream(cmdline); std::string command; if (!(cmdstream >> command)) return; con_debug << "Executing '" << cmdline << "'\n"; // is it a function Func *f = Func::find(command); if (f) { std::string args; char c; if (cmdstream >> args) { while (cmdstream >> c) args += c; } if ((f->flags() & Func::Game)) { if (game() && game()->connected) { f->exec(&Player::local, args); } } else { f->exec(args); } return; } // is it a cvar Cvar *cvar = Cvar::find(command); if (cvar) { // cvar exists std::string value; if (((cvar->flags() & Cvar::ReadOnly) == 0) && (cmdstream >> value)) { // we're setting a new value char c; while (cmdstream >> c) value += c; (*cvar) = value; } con_print << command << " " << cvar->str() << "\n"; return; } // TODO this must get forwarded to the server con_print << "Unknown command '" << command << "'\n"; } void CommandBuffer::exec() { if (cmdbuf.eof()) return; char line[MAXCMDSIZE]; while (core::cmd().getline(line, MAXCMDSIZE-1)) { exec(std::string(line)); } cmdbuf.clear(); } void CommandBuffer::complete(std::string &input, size_t &pos) { std::list match; std::string partial = input.substr(0, pos); if (!partial.size()) return; // search function registry for matches std::map::iterator f; for (f = Func::registry.begin(); f != Func::registry.end(); f++) { if (partial == (*f).first.substr(0, partial.size())) { match.push_back((*f).first); //con_print << " " << (*f).first << "\n"; } } // search cvar registry for matches std::map::iterator c; for (c = Cvar::registry.begin(); c != Cvar::registry.end(); c++) { if (partial == (*c).first.substr(0, partial.size())) { match.push_back((*c).first); //con_print << " " << (*c).first << "\n"; } } if (!match.size()) return; std::string maxmatch(*match.begin()); if (match.size() > 1) { std::list::iterator l; for (l = match.begin(); l !=match.end(); l++) { if (maxmatch.size()) { size_t i =0; while ((i < maxmatch.size() && i < (*l).size()) && (maxmatch[i] == (*l)[i])) { i++; } if (i < maxmatch.size()) maxmatch.erase(i); } con_print << " " << (*l) << "\n"; } con_print << match.size() << " matches\n"; } if (maxmatch.size() > partial.size()) { if (match.size()==1) maxmatch += ' '; input.replace(0, pos, maxmatch); pos = maxmatch.size(); } } }