Pol  Revision:cb584c9
cmdlevel.cpp
Go to the documentation of this file.
1 
8 #include "cmdlevel.h"
9 
10 #include <stddef.h>
11 #include <string>
12 
13 #include "../bscript/bstruct.h"
14 #include "../bscript/impstr.h"
15 #include "../clib/cfgelem.h"
16 #include "../clib/cfgfile.h"
17 #include "../clib/clib.h"
18 #include "../clib/dirlist.h"
19 #include "../clib/fileutil.h"
20 #include "../clib/stlutil.h"
21 #include "../clib/strutil.h"
22 #include "../plib/pkg.h"
23 #include "../plib/systemstate.h"
24 #include "globals/uvars.h"
25 namespace Pol
26 {
27 namespace Core
28 {
29 CmdLevel::CmdLevel( Clib::ConfigElem& elem, int cmdlevelnum )
30  : name( elem.rest() ), cmdlevel( static_cast<unsigned char>( cmdlevelnum ) )
31 {
33  std::string tmp;
34  while ( elem.remove_prop( "DIR", &tmp ) )
35  {
36  Clib::mklower( tmp );
37  add_searchdir( nullptr, Clib::normalized_dir_form( tmp ) );
38  }
39  while ( elem.remove_prop( "ALIAS", &tmp ) )
40  {
41  Clib::mklower( tmp );
42  aliases.push_back( tmp );
43  }
44 }
45 
46 bool CmdLevel::matches( const std::string& i_name ) const
47 {
48  if ( Clib::stringicmp( i_name, name ) == 0 )
49  return true;
50  for ( Aliases::const_iterator itr = aliases.begin(); itr != aliases.end(); ++itr )
51  {
52  if ( Clib::stringicmp( i_name, *itr ) == 0 )
53  return true;
54  }
55  return false;
56 }
57 void CmdLevel::add_searchdir( Plib::Package* pkg, const std::string& dir )
58 {
59  searchlist.emplace_back( SearchDir{pkg, dir} );
60 }
61 void CmdLevel::add_searchdir_front( Plib::Package* pkg, const std::string& dir )
62 {
63  searchlist.insert( searchlist.begin(), SearchDir{pkg, dir} );
64 }
65 
66 size_t CmdLevel::estimateSize() const
67 {
68  size_t size = name.capacity() + sizeof( unsigned char ); /*cmdlevel*/
69 
70  size += 3 * sizeof( SearchDir* );
71  for ( const auto& ele : searchlist )
72  {
73  size += sizeof( Plib::Package* ) + ele.dir.capacity();
74  }
75  size += 3 * sizeof( std::string* );
76  for ( const auto& ele : aliases )
77  {
78  size += ele.capacity();
79  }
80  return size;
81 }
82 
83 
84 CmdLevel* find_cmdlevel( const char* name )
85 {
86  for ( auto& cmdlvl : gamestate.cmdlevels )
87  {
88  if ( stricmp( name, cmdlvl.name.c_str() ) == 0 )
89  return &cmdlvl;
90  }
91  return nullptr;
92 }
93 
94 CmdLevel* FindCmdLevelByAlias( const std::string& str )
95 {
96  for ( auto& cmdlvl : gamestate.cmdlevels )
97  {
98  if ( cmdlvl.matches( str ) )
99  return &cmdlvl;
100  }
101  return nullptr;
102 }
103 
105 {
106  if ( cmdlvl_num >= static_cast<int>( gamestate.cmdlevels.size() ) )
107  cmdlvl_num = static_cast<int>( gamestate.cmdlevels.size() - 1 );
108 
109  CmdLevel& cmdlevel = gamestate.cmdlevels[cmdlvl_num];
110 
111  std::unique_ptr<Bscript::ObjArray> script_names( new Bscript::ObjArray );
112 
113  for ( unsigned diridx = 0; diridx < cmdlevel.searchlist.size(); ++diridx )
114  {
115  CmdLevel::SearchDir* search_dir = &cmdlevel.searchlist[diridx];
116  Plib::Package* pkg = search_dir->pkg;
117  std::string dir_name = search_dir->dir;
118  if ( ( !pkg && m_pkg ) || ( pkg && !m_pkg ) )
119  continue;
120  if ( pkg && m_pkg )
121  {
122  if ( pkg != m_pkg )
123  continue;
124  dir_name = std::string( pkg->dir().c_str() ) + dir_name;
125  }
126 
127  for ( Clib::DirList dl( dir_name.c_str() ); !dl.at_end(); dl.next() )
128  {
129  std::string name = dl.name(), ext;
130  if ( name[0] == '.' )
131  continue;
132 
133  std::string::size_type pos = name.rfind( '.' );
134  if ( pos != std::string::npos )
135  ext = name.substr( pos );
136 
137  if ( pos != std::string::npos && ( !ext.compare( ".ecl" ) ) )
138  {
139  std::unique_ptr<Bscript::BStruct> cmdinfo( new Bscript::BStruct );
140  cmdinfo->addMember( "dir", new Bscript::String( search_dir->dir ) );
141  cmdinfo->addMember( "script", new Bscript::String( name.c_str() ) );
142  script_names->addElement( cmdinfo.release() );
143  }
144  }
145  }
146  if ( script_names->ref_arr.size() > 0 )
147  return script_names.release();
148  else
149  return nullptr;
150 }
151 
153 {
154  Clib::ConfigFile cf( "config/cmds.cfg", "CmdLevel" );
155  Clib::ConfigElem elem;
156 
157  while ( cf.read( elem ) )
158  {
159  CmdLevel cmdlevel( elem, static_cast<int>( gamestate.cmdlevels.size() ) );
160  gamestate.cmdlevels.push_back( cmdlevel );
161  }
162 }
163 
165 {
166  // ConfigFile cf( (pkg->dir() + "cmds.cfg").c_str(), "Commands" );
167  Clib::ConfigFile cf( GetPackageCfgPath( pkg, "cmds.cfg" ).c_str(), "Commands" );
168  Clib::ConfigElem elem;
169  while ( cf.read( elem ) )
170  {
171  CmdLevel* cmdlevel = find_cmdlevel( elem.rest() );
172  if ( !cmdlevel )
173  {
174  elem.throw_error( std::string( "Command Level " ) + elem.rest() + " not found." );
175  }
176 
177  std::string tmp;
178  while ( elem.remove_prop( "DIR", &tmp ) )
179  {
180  Clib::mklower( tmp );
181  cmdlevel->add_searchdir_front( pkg, Clib::normalized_dir_form( pkg->dir() + tmp ) );
182  }
183  }
184 }
185 
186 // look for a "textcmd/cmdlevel" or "commands/cmdlevel" directory for each name and alias
188 {
189  for ( unsigned i = 0; i < gamestate.cmdlevels.size(); ++i )
190  {
192  std::string dir, part;
193 
194  // first check for the package name
195  part = "textcmd/" + cmdlevel.name + "/";
196  dir = pkg->dir() + part;
197  if ( Clib::FileExists( dir.c_str() ) )
198  cmdlevel.add_searchdir_front( pkg, part );
199 
200  part = "commands/" + cmdlevel.name + "/";
201  dir = pkg->dir() + part;
202  if ( Clib::FileExists( dir.c_str() ) )
203  cmdlevel.add_searchdir_front( pkg, part );
204 
205  // then each alias
206  for ( CmdLevel::Aliases::iterator itr = cmdlevel.aliases.begin(); itr != cmdlevel.aliases.end();
207  ++itr )
208  {
209  part = "textcmd/" + *itr + "/";
210  dir = pkg->dir() + part;
211  if ( Clib::FileExists( dir.c_str() ) )
212  cmdlevel.add_searchdir_front( pkg, part );
213 
214  part = "commands/" + *itr + "/";
215  dir = pkg->dir() + part;
216  if ( Clib::FileExists( dir.c_str() ) )
217  cmdlevel.add_searchdir_front( pkg, part );
218  }
219  }
220 }
221 
223 {
224  for ( Plib::Packages::iterator itr = Plib::systemstate.packages.begin();
225  itr != Plib::systemstate.packages.end(); ++itr )
226  {
227  Plib::Package* pkg = ( *itr );
228  std::string filename = Plib::GetPackageCfgPath( pkg, "cmds.cfg" );
229  if ( Clib::FileExists( filename.c_str() ) )
230  {
232  }
233  else
234  {
236  }
237  }
238 }
239 } // namespace Core
240 } // namespace Pol
Bscript::ObjArray * GetCommandsInPackage(Plib::Package *m_pkg, int cmdlvl_num)
Definition: cmdlevel.cpp:104
SystemState systemstate
Definition: systemstate.cpp:12
bool matches(const std::string &name) const
Definition: cmdlevel.cpp:46
bool at_end() const
Definition: dirlist.cpp:102
CmdLevels cmdlevels
Definition: uvars.h:137
void process_package_cmds_cfg(Plib::Package *pkg)
Definition: cmdlevel.cpp:164
void add_searchdir_front(Plib::Package *pkg, const std::string &dir)
Definition: cmdlevel.cpp:61
size_t estimateSize() const
Definition: cmdlevel.cpp:66
const char * rest() const
Definition: cfgfile.cpp:71
POL_NORETURN void throw_error(const std::string &errmsg) const
Definition: cfgfile.cpp:285
unsigned char cmdlevel
Definition: cmdlevel.h:39
std::string name
Definition: cmdlevel.h:38
GameState gamestate
Definition: uvars.cpp:74
void add_searchdir(Plib::Package *pkg, const std::string &dir)
Definition: cmdlevel.cpp:57
bool remove_prop(const char *propname, std::string *value)
Definition: cfgfile.cpp:128
int stringicmp(const S1 &str1, const S2 &str2)
Definition: stlutil.h:46
void implicit_package_cmds_cfg(Plib::Package *pkg)
Definition: cmdlevel.cpp:187
void load_cmdlevels()
Definition: cmdlevel.cpp:152
CmdLevel * find_cmdlevel(const char *name)
Definition: cmdlevel.cpp:84
std::string name
Definition: osmod.cpp:943
std::string GetPackageCfgPath(const Package *pkg, const std::string &filename)
Definition: pkg.cpp:491
void load_package_cmdlevels()
Definition: cmdlevel.cpp:222
void mklower(std::string &str)
Definition: strutil.cpp:266
std::string normalized_dir_form(const std::string &istr)
Definition: fileutil.cpp:25
bool FileExists(const char *filename)
Definition: fileutil.cpp:118
bool read(ConfigElem &elem)
Definition: cfgfile.cpp:1015
CmdLevel(Clib::ConfigElem &elem, int cmdlevelnum)
Definition: cmdlevel.cpp:29
SearchList searchlist
Definition: cmdlevel.h:48
Definition: berror.cpp:12
const std::string & dir() const
Definition: pkg.h:79
CmdLevel * FindCmdLevelByAlias(const std::string &str)
Definition: cmdlevel.cpp:94