Pol  Revision:3cfda13
acscrobj.cpp
Go to the documentation of this file.
1 
23 #include "acscrobj.h"
24 
25 #include <stddef.h>
26 #include <string>
27 
28 #include "../../bscript/berror.h"
29 #include "../../bscript/executor.h"
30 #include "../../bscript/impstr.h"
31 #include "../../bscript/objmembers.h"
32 #include "../../bscript/objmethods.h"
33 #include "../../clib/clib_MD5.h"
34 #include "../../plib/systemstate.h"
35 #include "../core.h"
36 #include "../globals/uvars.h"
37 #include "../mobile/charactr.h"
38 #include "../network/client.h"
39 #include "../polcfg.h"
40 #include "../ufunc.h"
41 #include "../uoscrobj.h"
42 #include "account.h"
43 #include "accounts.h"
44 
45 namespace Pol
46 {
47 namespace Core
48 {
49 void call_ondelete_scripts( Mobile::Character* chr );
50 bool can_delete_character( Mobile::Character* chr, int delete_by );
51 void delete_character( Accounts::Account* acct, Mobile::Character* chr, int charidx );
52 void createchar2( Accounts::Account* acct, unsigned index );
53 }
54 namespace Accounts
55 {
57 
58 const char* AccountObjImp::typeOf() const
59 {
60  return "AccountRef";
61 }
62 u8 AccountObjImp::typeOfInt() const
63 {
64  return OTAccountRef;
65 }
66 
67 Bscript::BObjectImp* AccountObjImp::copy() const
68 {
69  return new AccountObjImp( obj_ );
70 }
71 
80 Bscript::BObjectImp* AccountObjImp::call_method_id( const int id, Bscript::Executor& ex,
81  bool /*forcebuiltin*/ )
82 {
83  using namespace Bscript;
84  BObjectImp* result = NULL;
85 
86  switch ( id )
87  {
88  case MTH_GET_MEMBER:
89  {
90  if ( !ex.hasParams( 1 ) )
91  return new BError( "Not enough parameters" );
92 
93  const String* mname;
94  if ( ex.getStringParam( 0, mname ) )
95  {
96  BObjectRef ref_temp = get_member( mname->value().c_str() );
97  BObjectRef& ref = ref_temp;
98  BObject* bo = ref.get();
99  BObjectImp* ret = bo->impptr();
100  ret = ret->copy();
101  if ( ret->isa( OTUninit ) )
102  {
103  std::string message = std::string( "Member " ) + std::string( mname->value() ) +
104  std::string( " not found on that object" );
105  return new BError( message );
106  }
107  else
108  {
109  return ret;
110  }
111  }
112  else
113  return new BError( "Invalid parameter type" );
114  break;
115  }
119  case MTH_BAN:
120  if ( ex.numParams() == 0 )
121  {
122  obj_->banned_ = true;
123  for ( unsigned short i = 0; i < Plib::systemstate.config.character_slots; i++ )
124  {
125  Mobile::Character* chr = obj_->get_character( i );
126  if ( chr && chr->client )
127  chr->client->Disconnect();
128  }
129  }
130  else
131  return new BError( "account.Ban() doesn't take parameters." );
132  break;
136  case MTH_UNBAN:
137  if ( ex.numParams() == 0 )
138  obj_->banned_ = false;
139  else
140  return new BError( "account.Unban() doesn't take parameters." );
141  break;
145  case MTH_ENABLE:
146  if ( ex.numParams() == 0 )
147  obj_->enabled_ = true;
148  else
149  return new BError( "account.Enable() doesn't take parameters." );
150  break;
154  case MTH_DISABLE:
155  if ( ex.numParams() == 0 )
156  {
157  obj_->enabled_ = false;
158  for ( unsigned short i = 0; i < Plib::systemstate.config.character_slots; i++ )
159  {
160  Mobile::Character* chr = obj_->get_character( i );
161  if ( chr && chr->client )
162  chr->client->Disconnect();
163  }
164  break;
165  }
166  else
167  return new BError( "account.Disable() doesn't take parameters." );
171  case MTH_SETPASSWORD:
172  if ( ex.numParams() == 1 )
173  {
174  const String* pwstr;
175  if ( ex.getStringParam( 0, pwstr ) )
176  {
177  if ( Plib::systemstate.config.retain_cleartext_passwords )
178  obj_->password_ = pwstr->value();
179 
180  std::string temp;
181  Clib::MD5_Encrypt( obj_->name_ + pwstr->value(), temp );
182  obj_->passwordhash_ = temp; // MD5
183  break;
184  }
185  else
186  {
187  return new BError( "Invalid parameter type" );
188  }
189  }
190  else
191  return new BError( "account.SetPassword(newpass) requires a parameter." );
195  case MTH_CHECKPASSWORD:
196  if ( ex.numParams() == 1 )
197  {
198  const String* pwstr;
199  if ( ex.getStringParam( 0, pwstr ) )
200  {
201  bool ret;
202  std::string temp;
203 
204  Clib::MD5_Encrypt( obj_->name_ + pwstr->value(), temp ); // MD5
205  ret = Clib::MD5_Compare( obj_->passwordhash_, temp );
206 
207  result = new BLong( ret );
208  }
209  else
210  {
211  return new BError( "Invalid parameter type" );
212  }
213  }
214  else
215  return new BError( "account.CheckPassword(password) requires a parameter." );
216  break;
225  case MTH_SETNAME:
226  // passed only new account name, and cleartext password is saved
227  if ( ( ex.numParams() == 1 ) && Plib::systemstate.config.retain_cleartext_passwords )
228  {
229  const String* nmstr;
230  if ( ex.getStringParam( 0, nmstr ) )
231  {
232  if ( nmstr->value().empty() )
233  return new BError( "Account name must not be empty." );
234  std::string temp;
235  // passing the new name, and recalc name+pass hash (pass only hash is unchanged)
236  obj_->name_ = nmstr->value();
237  Clib::MD5_Encrypt( obj_->name_ + obj_->password_, temp );
238  obj_->passwordhash_ = temp; // MD5
239  }
240  else
241  {
242  return new BError( "Invalid parameter type" );
243  }
244  }
245  // passed new account name and password
246  else if ( ex.numParams() == 2 )
247  {
248  const String* nmstr;
249  const String* pwstr;
250  if ( ex.getStringParam( 0, nmstr ) && ex.getStringParam( 1, pwstr ) )
251  {
252  if ( nmstr->value().empty() )
253  return new BError( "Account name must not be empty." );
254  obj_->name_ = nmstr->value();
255  // this is the same as the "setpassword" code above
256  if ( Plib::systemstate.config.retain_cleartext_passwords )
257  obj_->password_ = pwstr->value();
258 
259  std::string temp;
260  Clib::MD5_Encrypt( obj_->name_ + pwstr->value(), temp );
261  obj_->passwordhash_ = temp; // MD5
262  }
263  else
264  {
265  return new BError( "Invalid parameter type" );
266  }
267  }
268  else if ( ( ex.numParams() == 1 ) && !Plib::systemstate.config.retain_cleartext_passwords )
269  return new BError( "Usage: account.SetName(name,pass) if RetainCleartextPasswords is off." );
270  else
271  return new BError( "account.SetName needs at least 1 parameter." );
272  break;
286  case MTH_GETPROP:
287  case MTH_SETPROP:
288  case MTH_ERASEPROP:
289  case MTH_PROPNAMES:
290  {
291  bool changed = false;
292  result = CallPropertyListMethod_id( obj_->props_, id, ex, changed );
293  if ( result && !changed )
294  return result;
295  break;
296  }
298  {
299  if ( ex.numParams() != 1 )
300  return new BError( "account.SetDefaultCmdLevel(int) requires a parameter." );
301 
302  int cmdlevel;
303  if ( !ex.getParam( 0, cmdlevel ) )
304  return new BError( "Invalid parameter type." );
305  else if ( cmdlevel >= static_cast<int>( Core::gamestate.cmdlevels.size() ) )
306  cmdlevel = static_cast<int>( Core::gamestate.cmdlevels.size() - 1 );
307 
308  obj_->default_cmdlevel_ = char( cmdlevel );
309 
310  break;
311  }
316  case MTH_GETCHARACTER:
317  {
318  if ( ex.numParams() != 1 )
319  return new BError( "account.GetCharacter(index) requires a parameter." );
320  int index;
321  if ( !ex.getParam( 0, index, 1, Plib::systemstate.config.character_slots ) )
322  return NULL;
323  Mobile::Character* chr = obj_->get_character( index - 1 );
324 
325  if ( chr == NULL )
326  return new BError( "No such character on this account" );
327  return new Module::EOfflineCharacterRefObjImp( chr );
328  }
333  case MTH_DELETECHARACTER:
334  {
335  if ( ex.numParams() != 1 )
336  return new BError( "account.DeleteCharacter(index) requires a parameter." );
337  int index;
338  if ( !ex.getParam( 0, index, 1, Plib::systemstate.config.character_slots ) )
339  return NULL;
340  Mobile::Character* chr = obj_->get_character( index - 1 );
341 
342  if ( chr == NULL )
343  return new BError( "No such character on this account" );
344  if ( chr->client != NULL || chr->logged_in() )
345  return new BError( "That character is in use" );
346 
348  {
349  call_ondelete_scripts( chr );
350  delete_character( obj_.Ptr(), chr, index - 1 );
351  }
352  else
353  return new BError( "CanDelete blocks Character deletion." );
354 
355  break;
356  }
363  if ( ex.numParams() != 1 )
364  return new BError( "account.Set_UO_Expansion(string) requires a parameter." );
365 
366  const String* expansion_str;
367  if ( ex.getStringParam( 0, expansion_str ) )
368  {
369  if ( expansion_str->value().empty() || ( expansion_str->value() == "TOL" ) ||
370  ( expansion_str->value() == "HSA" ) || ( expansion_str->value() == "SA" ) ||
371  ( expansion_str->value() == "KR" ) || ( expansion_str->value() == "ML" ) ||
372  ( expansion_str->value() == "SE" ) || ( expansion_str->value() == "AOS" ) ||
373  ( expansion_str->value() == "LBR" ) || ( expansion_str->value() == "T2A" ) )
374  {
375  obj_->uo_expansion_ = obj_->convert_uo_expansion( expansion_str->value() );
376  for ( unsigned short i = 0; i < Plib::systemstate.config.character_slots; i++ )
377  {
378  Mobile::Character* chr = obj_->get_character( i );
379  if ( chr && chr->has_active_client() )
381  }
382  }
383  else
384  return new BError(
385  "Invalid Parameter Value. Supported Values: \"\", T2A, LBR, AOS, SE, ML, KR, SA, HSA, "
386  "TOL" );
387  }
388  else
389  return new BError( "Invalid Parameter Type" );
390  break;
394  case MTH_DELETE:
395  if ( ex.numParams() == 0 )
396  {
397  int _result = delete_account( obj_->name() );
398  if ( _result == -1 )
399  return new BError( "You must delete all Character first." );
400  else if ( _result == -2 ) // Should never happen ;o)
401  return new BError( "Invalid Account Name." );
402  }
403  else
404  return new BError( "account.Delete() doesn't take parameters." );
405  break;
410  case MTH_SPLIT:
411  if ( ex.numParams() == 2 )
412  {
413  const String* acctname;
414  int index;
415  if ( ex.getStringParam( 0, acctname ) &&
416  ex.getParam( 1, index, 1, Plib::systemstate.config.character_slots ) )
417  {
418  if ( acctname->value().empty() )
419  return new BError( "Account name must not be empty." );
420 
421  if ( find_account( acctname->data() ) )
422  return new BError( "Account already exists." );
423 
424  Mobile::Character* chr = obj_->get_character( index - 1 );
425 
426  if ( chr == NULL )
427  return new BError( "No such character on this account." );
428  if ( chr->client != NULL || chr->logged_in() )
429  return new BError( "That character is in use." );
430 
431  Account* account = duplicate_account( obj_->name_, acctname->value() );
432  if ( account != NULL )
433  {
434  obj_->clear_character( index - 1 );
435  chr->acct.set( account );
436  account->set_character( 0, chr );
437  }
438  else
439  return new BError( "Was impossible to create new Account." );
440  }
441  else
442  return new BError( "Invalid parameter type." );
443  }
444  else
445  return new BError( "account.Split requires two parameters." );
446  break;
451  case MTH_MOVE_CHAR:
452  if ( ex.numParams() == 2 )
453  {
454  const String* acctname;
455  int index;
456  if ( ex.getStringParam( 0, acctname ) &&
457  ex.getParam( 1, index, 1, Plib::systemstate.config.character_slots ) )
458  {
459  if ( acctname->value().empty() )
460  return new BError( "Account name must not be empty." );
461 
462  Account* account = find_account( acctname->data() );
463  if ( account == NULL )
464  return new BError( "Account doesn't exists." );
465 
466  Mobile::Character* chr = obj_->get_character( index - 1 );
467 
468  if ( chr == NULL )
469  return new BError( "No such character on this account." );
470  if ( chr->client != NULL || chr->logged_in() )
471  return new BError( "That character is in use." );
472 
473  int charid = account->getnextfreeslot();
474  if ( charid != -1 )
475  {
476  obj_->clear_character( index - 1 );
477  chr->acct.set( account );
478  account->set_character( charid - 1, chr );
479  }
480  else
481  return new BError( "Account is full." );
482  }
483  else
484  return new BError( "Invalid parameter type." );
485  }
486  else
487  return new BError( "account.Move_Char requires two parameters." );
488  break;
489  case MTH_ADD_CHARACTER:
490  {
491  int index;
492  if ( !ex.getParam( 0, index, 0, Plib::systemstate.config.character_slots ) )
493  return new BError( "Account.AddCharacter() requires one parameter." );
494 
495  if ( index <= 0 )
496  {
497  index = obj_->getnextfreeslot();
498  if ( index == -1 )
499  return new BError( "Account has no free character slots." );
500  }
501 
502  // We take in 1-5 to match account.GetCharacter()
503  // Internally it uses it as 0-4
504  index--;
505 
506  if ( obj_->get_character( index ) )
507  {
508  return new BError( "That character slot is already in use." );
509  }
510 
511  result = new BLong( index + 1 );
512  Account* acct = find_account( obj_->name_.c_str() );
513  if ( acct == NULL )
514  {
515  return new BError( "Account doesn't exist." );
516  }
517  Core::createchar2( acct, unsigned( index ) );
518 
519  break;
520  }
521  default:
522  return NULL;
523  }
524 
525  // if any of the methods hit & worked, we'll come here
526  if ( Plib::systemstate.config.account_save == -1 )
528  else
530  return result ? result : new BLong( 1 );
531 }
532 
533 
542 Bscript::BObjectImp* AccountObjImp::call_method( const char* methodname, Bscript::Executor& ex )
543 {
544  Bscript::ObjMethod* objmethod = Bscript::getKnownObjMethod( methodname );
545  if ( objmethod != NULL )
546  return this->call_method_id( objmethod->id, ex );
547  else
548  return NULL;
549 }
550 
558 
559 Bscript::BObjectRef AccountObjImp::get_member_id( const int id ) // id test
560 {
561  using namespace Bscript;
562  switch ( id )
563  {
564  case MBR_NAME:
565  return BObjectRef( new String( obj_->name() ) );
566  break;
567  case MBR_ENABLED:
568  return BObjectRef( new BLong( obj_->enabled() ) );
569  break;
570  case MBR_BANNED:
571  return BObjectRef( new BLong( obj_->banned() ) );
572  break;
574  return BObjectRef( new String( obj_->passwordhash() ) );
575  break;
576  case MBR_UO_EXPANSION:
577  return BObjectRef( new String( obj_->uo_expansion() ) );
578  break;
579  case MBR_DEFAULTCMDLEVEL:
580  return BObjectRef( new BLong( obj_->default_cmdlevel_ ) );
581  break;
582  default:
583  return BObjectRef( UninitObject::create() );
584  break;
585  }
586 }
587 
588 Bscript::BObjectRef AccountObjImp::get_member( const char* membername )
589 {
590  using namespace Bscript;
591  ObjMember* objmember = getKnownObjMember( membername );
592  if ( objmember != NULL )
593  return this->get_member_id( objmember->id );
594  else
595  return BObjectRef( UninitObject::create() );
596 }
597 }
598 }
unsigned char u8
Definition: rawtypes.h:25
bool MD5_Encrypt(const std::string &in, std::string &out)
Definition: clib_MD5.cpp:97
void set_character(int index, Mobile::Character *chr)
Definition: account.cpp:174
void clear_character(int index)
Definition: account.cpp:179
SystemState systemstate
Definition: systemstate.cpp:12
Network::Client * client
Definition: charactr.h:871
Core::PolConfig config
Definition: systemstate.h:43
Account * duplicate_account(const std::string &oldacctname, const std::string &newacctname)
Definition: accounts.cpp:128
ObjMember * getKnownObjMember(const char *token)
Definition: parser.cpp:483
void delete_character(Accounts::Account *acct, Mobile::Character *chr, int charidx)
Definition: login.cpp:472
void write_account_data()
Definition: accounts.cpp:71
Bscript::BApplicObjType accountobjimp_type
Definition: acscrobj.cpp:56
bool has_active_client() const
Definition: charactr.cpp:448
const int DELETE_BY_SCRIPT
Definition: core.h:59
bool logged_in() const
Definition: charactr.cpp:428
void call_ondelete_scripts(Mobile::Character *chr)
Definition: pol.cpp:378
CmdLevels cmdlevels
Definition: uvars.h:137
ObjMethod * getKnownObjMethod(const char *token)
Definition: parser.cpp:665
Bscript::BObjectImp * CallPropertyListMethod_id(PropertyList &proplist, const int id, Bscript::Executor &ex, bool &changed)
Definition: proplist.cpp:520
int getnextfreeslot() const
Definition: account.cpp:296
void send_feature_enable(Client *client)
Definition: ufunc.cpp:1953
static UninitObject * create()
Definition: bobject.h:482
void createchar2(Accounts::Account *acct, unsigned index)
Definition: create.cpp:570
int delete_account(const char *acctname)
Definition: accounts.cpp:163
size_t numParams() const
Definition: executor.h:145
GameState gamestate
Definition: uvars.cpp:74
Core::AccountRef acct
Definition: charactr.h:914
const String * getStringParam(unsigned param)
Definition: executor.cpp:347
bool MD5_Compare(const std::string &a, const std::string &b)
Definition: clib_MD5.cpp:119
bool hasParams(unsigned howmany) const
Definition: executor.h:144
bool can_delete_character(Mobile::Character *chr, int delete_by)
Definition: pol.cpp:363
void set(T *ptr)
Definition: refptr.h:275
unsigned short character_slots
Definition: polcfg.h:65
Definition: berror.cpp:12
Account * find_account(const char *acctname)
Definition: accounts.cpp:151
bool getParam(unsigned param, int &value)
Definition: executor.cpp:363