Pol  Revision:cb584c9
accounts.cpp
Go to the documentation of this file.
1 
11 #include "accounts.h"
12 
13 #include <iosfwd>
14 #include <stdio.h>
15 #include <string.h>
16 #include <sys/stat.h>
17 #include <time.h>
18 
19 #include "../../clib/cfgelem.h"
20 #include "../../clib/cfgfile.h"
21 #include "../../clib/clib.h"
22 #include "../../clib/logfacility.h"
23 #include "../../clib/passert.h"
24 #include "../../clib/streamsaver.h"
25 #include "../../clib/timer.h"
26 #include "../../plib/systemstate.h"
27 #include "../globals/state.h"
28 #include "../globals/uvars.h"
29 #include "../polsig.h"
30 #include "account.h"
31 
32 namespace Pol
33 {
34 namespace Accounts
35 {
37 {
38  unsigned int naccounts = 0;
39  static int num_until_dot = 1000;
40  Tools::Timer<> timer;
41 
42  std::string accountsfile = Plib::systemstate.config.world_data_path + "accounts.txt";
43 
44  INFO_PRINT << " " << accountsfile << ":";
45  stat( accountsfile.c_str(), &Plib::systemstate.accounts_txt_stat );
46 
47  {
48  Clib::ConfigFile cf( accountsfile, "Account" );
49  Clib::ConfigElem elem;
50 
51  while ( cf.read( elem ) )
52  {
53  if ( --num_until_dot == 0 )
54  {
55  INFO_PRINT << ".";
56  num_until_dot = 1000;
57  }
58  Core::gamestate.accounts.push_back( Core::AccountRef( new Account( elem ) ) );
59  naccounts++;
60  }
61  }
62 
63  if ( Plib::systemstate.accounts_txt_dirty )
64  {
66  }
67 
68  INFO_PRINT << " " << naccounts << " elements in " << timer.ellapsed() << " ms.\n";
69 }
70 
72 {
73  std::string accountstxtfile = Plib::systemstate.config.world_data_path + "accounts.txt";
74  std::string accountsbakfile = Plib::systemstate.config.world_data_path + "accounts.bak";
75  std::string accountsndtfile = Plib::systemstate.config.world_data_path + "accounts.ndt";
76  const char* accountstxtfile_c = accountstxtfile.c_str();
77  const char* accountsbakfile_c = accountsbakfile.c_str();
78  const char* accountsndtfile_c = accountsndtfile.c_str();
79 
80  unlink( accountsbakfile_c );
81  unlink( accountsndtfile_c );
82 
83  try
84  {
85  std::ofstream ofs( accountsndtfile_c, std::ios::trunc | std::ios::out );
86  Clib::OFStreamWriter sw( &ofs );
87  for ( const auto& account : Core::gamestate.accounts )
88  {
89  Account* acct = account.get();
90  acct->writeto( sw );
91  }
92  }
93  catch ( ... )
94  {
95  POLLOG_ERROR << "failed to store accounts!\n";
97  }
98 
99  rename( accountstxtfile_c, accountsbakfile_c );
100  rename( accountsndtfile_c, accountstxtfile_c );
101 
102  struct stat newst;
103  stat( accountstxtfile_c, &newst );
104  memcpy( &Plib::systemstate.accounts_txt_stat, &newst,
105  sizeof Plib::systemstate.accounts_txt_stat );
107 }
108 
109 Account* create_new_account( const std::string& acctname, const std::string& password,
110  bool enabled )
111 {
112  passert( !find_account( acctname.c_str() ) );
113 
114  Clib::ConfigElem elem;
115  elem.add_prop( "name", acctname );
116  elem.add_prop( "password", password );
117 
118  elem.add_prop( "enabled", ( (unsigned int)( enabled ? 1 : 0 ) ) );
119  auto acct = new Account( elem );
120  Core::gamestate.accounts.push_back( Core::AccountRef( acct ) );
121  if ( Plib::systemstate.config.account_save == -1 )
123  else
125  return acct;
126 }
127 
128 Account* duplicate_account( const std::string& oldacctname, const std::string& newacctname )
129 {
130  passert( !find_account( newacctname.c_str() ) );
131 
132  Account* oldacct = find_account( oldacctname.c_str() );
133  if ( oldacct != nullptr )
134  {
135  Clib::ConfigElem elem;
136  oldacct->writeto( elem );
137  elem.remove_string( "name" );
138  elem.add_prop( "name", newacctname );
139 
140  auto acct = new Account( elem );
141  Core::gamestate.accounts.push_back( Core::AccountRef( acct ) );
142  if ( Plib::systemstate.config.account_save == -1 )
144  else
146  return acct;
147  }
148  return nullptr;
149 }
150 
151 Account* find_account( const char* acctname )
152 {
153  for ( auto& account : Core::gamestate.accounts )
154  {
155  if ( stricmp( account->name(), acctname ) == 0 )
156  {
157  return account.get();
158  }
159  }
160  return nullptr;
161 }
162 
163 int delete_account( const char* acctname )
164 {
165  for ( auto itr = Core::gamestate.accounts.begin(), end = Core::gamestate.accounts.end();
166  itr != end; ++itr )
167  {
168  Account* account = ( *itr ).get();
169  if ( stricmp( account->name(), acctname ) == 0 )
170  {
171  if ( account->numchars() == 0 )
172  {
173  Core::gamestate.accounts.erase( itr );
174  if ( Plib::systemstate.config.account_save == -1 )
176  else
178  return 1;
179  }
180  else
181  return -1;
182  }
183  }
184  return -2;
185 }
186 
188 {
189  std::string name = elem.remove_string( "NAME" );
190  Account* existing = find_account( name.c_str() );
191  if ( existing != nullptr )
192  {
193  existing->readfrom( elem );
194  }
195  else
196  {
197  elem.add_prop( "NAME", name );
198  Core::gamestate.accounts.push_back( Core::AccountRef( new Account( elem ) ) );
199  }
200 }
201 
203 {
204  THREAD_CHECKPOINT( tasks, 500 );
205  try
206  {
207  std::string accountsfile = Plib::systemstate.config.world_data_path + "accounts.txt";
208 
209  struct stat newst;
210  stat( accountsfile.c_str(), &newst );
211  if ( ( newst.st_mtime != Plib::systemstate.accounts_txt_stat.st_mtime ) &&
212  ( newst.st_mtime < time( nullptr ) - 10 ) )
213  {
214  INFO_PRINT << "Reloading accounts.txt...";
215  memcpy( &Plib::systemstate.accounts_txt_stat, &newst,
216  sizeof Plib::systemstate.accounts_txt_stat );
217 
218  {
219  Clib::ConfigFile cf( accountsfile, "Account" );
220  Clib::ConfigElem elem;
221  while ( cf.read( elem ) )
222  {
223  reread_account( elem );
224  }
225  INFO_PRINT << "Done!\n";
226  }
227  if ( Plib::systemstate.accounts_txt_dirty )
228  {
230  }
231  }
232  }
233  catch ( ... )
234  {
235  INFO_PRINT << "Error reading accounts.txt!\n";
236  }
237  THREAD_CHECKPOINT( tasks, 599 );
238 }
239 
241 {
242  if ( Plib::systemstate.accounts_txt_dirty )
244 }
245 } // namespace Accounts
246 } // namespace Pol
AccountsVector accounts
Definition: uvars.h:144
std::string remove_string(const char *propname)
Definition: cfgfile.cpp:381
Account * create_new_account(const std::string &acctname, const std::string &password, bool enabled)
Definition: accounts.cpp:109
void readfrom(Clib::ConfigElem &elem)
Definition: account.cpp:47
SystemState systemstate
Definition: systemstate.cpp:12
Core::PolConfig config
Definition: systemstate.h:43
std::string world_data_path
Definition: polcfg.h:28
Account * duplicate_account(const std::string &oldacctname, const std::string &newacctname)
Definition: accounts.cpp:128
void write_account_data()
Definition: accounts.cpp:71
#define THREAD_CHECKPOINT(thread, check)
Definition: polsig.h:48
void force_backtrace(bool complete)
Definition: passert.cpp:53
#define POLLOG_ERROR
Definition: logfacility.h:207
void reload_account_data(void)
Definition: accounts.cpp:202
void add_prop(std::string propname, std::string propval)
Definition: cfgfile.cpp:490
const char * name() const
Definition: account.cpp:193
void reread_account(Clib::ConfigElem &elem)
Definition: accounts.cpp:187
int numchars() const
Definition: account.cpp:287
#define passert(exp)
Definition: passert.h:62
void write_account_data_task(void)
Definition: accounts.cpp:240
int delete_account(const char *acctname)
Definition: accounts.cpp:163
GameState gamestate
Definition: uvars.cpp:74
long long ellapsed() const
Definition: timer.cpp:46
std::string name
Definition: osmod.cpp:943
struct stat accounts_txt_stat
Definition: systemstate.h:41
void writeto(Clib::StreamWriter &sw) const
Definition: account.cpp:84
void read_account_data()
Definition: accounts.cpp:36
bool read(ConfigElem &elem)
Definition: cfgfile.cpp:1015
#define INFO_PRINT
Definition: logfacility.h:223
Definition: berror.cpp:12
Account * find_account(const char *acctname)
Definition: accounts.cpp:151