BObjectImp* PolSystemExecutorModule::mf_Realms( /* realm_name:="" */ ) { const String* realm_name; // getStringParam(0, realm_name); BObjectImp* imp = getParamImp( 0 ); if (imp->isa( BObjectImp::OTString )) { realm_name = static_cast<const String*>(imp); } else { return new BError( string("Parameter must be a String or empty, got ") + BObjectImp::typestr( imp->type() ) ); } if ( realm_name->length() > 0 ) { Realm* realm = find_realm(realm_name->value()); if( !realm ) return new BError("Realm not found."); else return SetupRealmDetails(realm); } else { BDictionary* dict = new BDictionary; vector<Realm*>::iterator itr; for( itr = Realms->begin(); itr != Realms->end(); ++itr ) { dict->addMember((*itr)->name().c_str(), SetupRealmDetails(*itr)); } return dict; } }
BObjectImp* UOExecutorModule::internal_MoveContainer(UContainer* container, xcoord x, ycoord y, zcoord z, long flags, Realm* newrealm) { Realm* oldrealm = container->realm; BObjectImp* ok = internal_MoveItem(static_cast<Item*>(container), x, y, z, flags, newrealm); // Check if container was successfully moved to a new realm and update contents. if ( !ok->isa( BObjectImp::OTError ) ) { if ( newrealm != NULL && oldrealm != newrealm ) container->for_each_item(setrealm, (void*)newrealm); } return ok; }
int ExportScript::call_long( unsigned PC, BObjectImp* p0, BObjectImp* p1 ) { try { //build backup if function is called inside the same script BackupStruct backup; SaveStack( backup ); uoexec.initForFnCall( PC ); uoexec.pushArg( p0 ); uoexec.pushArg( p1 ); uoexec.exec(); int ret; if ( uoexec.error() ) ret = 0; else if ( uoexec.ValueStack.empty() ) ret = 0; else { BObjectImp* imp = uoexec.ValueStack.back().get()->impptr(); if ( imp->isa( BObjectImp::OTLong ) ) { BLong* pLong = static_cast<BLong*>( imp ); ret = pLong->value(); } else { ret = 0; } uoexec.ValueStack.pop_back(); } // delete current state and reenable backup LoadStack( backup ); return ret; } catch ( std::exception& )//... { return 0; } }
bool EGuildRefObjImp::isEqual(const BObjectImp& objimp) const { if (objimp.isa( BObjectImp::OTApplicObj )) { const BApplicObjBase* aob = explicit_cast<const BApplicObjBase*, const BObjectImp*>(&objimp); if (aob->object_type() == &guild_type) { const EGuildRefObjImp* guildref_imp = explicit_cast<const EGuildRefObjImp*,const BApplicObjBase*>(aob); return (guildref_imp->obj_->_guildid == obj_->_guildid); } else return false; } else return false; }
long ExportScript::call_long( unsigned PC, BObjectImp* p0, BObjectImp* p1 ) { try { uoexec.initForFnCall( PC ); uoexec.pushArg(p0); uoexec.pushArg(p1); uoexec.exec(); if (uoexec.error()) return 0; if (uoexec.ValueStack.empty()) return 0; long ret; BObjectImp* imp = uoexec.ValueStack.top().get()->impptr(); if (imp->isa( BObjectImp::OTLong )) { BLong* pLong = static_cast<BLong*>(imp); ret = pLong->value(); } else { ret = 0; } uoexec.ValueStack.pop(); return ret; } catch(std::exception&)//... { return 0; } }
BObjectImp* ScriptExObjImp::call_method_id( const int id, Executor& ex, bool forcebuiltin ) { if (!value().exists()) return new BError( "Script has been destroyed" ); UOExecutor* uoexec = value().get_weakptr(); OSExecutorModule* osemod = uoexec->os_module; switch(id) { case MTH_GET_MEMBER: { if ( !ex.hasParams(1) ) return new BError("Not enough parameters"); const String* mname; if ( ex.getStringParam(0, mname) ) { BObjectRef ref_temp = get_member(mname->value().c_str()); BObjectRef& ref = ref_temp; BObject *bo = ref.get(); BObjectImp *ret = bo->impptr(); ret = ret->copy(); if ( ret->isa(OTUninit) ) { string message = string("Member ") + string(mname->value()) + string(" not found on that object"); return new BError(message); } else { return ret; } } else return new BError( "Invalid parameter type" ); break; } case MTH_SENDEVENT: { if (!ex.hasParams(1)) return new BError( "Not enough parameters" ); BObjectImp* param0 = ex.getParamImp( 0 ); if (osemod->signal_event( param0->copy() )) return new BLong(1); else return new BError( "Event queue is full, discarding event" ); } case MTH_KILL: uoexec->seterror(true); // A Sleeping script would otherwise sit and wait until it wakes up to be killed. osemod->revive(); if (osemod->in_debugger_holdlist()) osemod->revive_debugged(); return new BLong(1); case MTH_LOADSYMBOLS: { int res = const_cast<EScriptProgram*>(uoexec->prog())->read_dbg_file(); return new BLong(!res); } case MTH_CLEAR_EVENT_QUEUE://DAVE added this 11/20 return (osemod->clear_event_queue()); default: return new BError( "undefined" ); } }
/// /// [1] Account Scripting Object Methods /// /// All methods except GetProp and GetCharacter return 1 on success /// All methods except GetProp and GetCharacter write the accounts.txt file on success. /// All methods return Error("Not enough parameters") if too few parameters were passed. /// All methods return Error("Invalid parameter type") if the wrong type was passed. /// Bscript::BObjectImp* AccountObjImp::call_method_id( const int id, Bscript::Executor& ex, bool forcebuiltin ) { using namespace Bscript; BObjectImp* result = NULL; switch ( id ) { case MTH_GET_MEMBER: { if ( !ex.hasParams( 1 ) ) return new BError( "Not enough parameters" ); const String* mname; if ( ex.getStringParam( 0, mname ) ) { BObjectRef ref_temp = get_member( mname->value().c_str() ); BObjectRef& ref = ref_temp; BObject *bo = ref.get(); BObjectImp *ret = bo->impptr(); ret = ret->copy(); if ( ret->isa( OTUninit ) ) { string message = string( "Member " ) + string( mname->value() ) + string( " not found on that object" ); return new BError( message ); } else { return ret; } } else return new BError( "Invalid parameter type" ); break; } /// /// account.Ban() : bans the account. Disconnects connected client if any. /// case MTH_BAN: if ( ex.numParams() == 0 ) { obj_->banned_ = true; if ( obj_->active_character ) { if ( obj_->active_character->client ) obj_->active_character->client->Disconnect(); } } else return new BError( "account.Ban() doesn't take parameters." ); break; /// /// account.Unban() : unbans the account. /// case MTH_UNBAN: if ( ex.numParams() == 0 ) obj_->banned_ = false; else return new BError( "account.Unban() doesn't take parameters." ); break; /// /// account.Enable() : enables the account /// case MTH_ENABLE: if ( ex.numParams() == 0 ) obj_->enabled_ = true; else return new BError( "account.Enable() doesn't take parameters." ); break; /// /// account.Disable() : disables the account. Disconnects connected client if any. /// case MTH_DISABLE: if ( ex.numParams() == 0 ) { obj_->enabled_ = false; if ( obj_->active_character ) { if ( obj_->active_character->client ) obj_->active_character->client->Disconnect(); } break; } else return new BError( "account.Disable() doesn't take parameters." ); /// /// account.SetPassword( newpassword : string ) : changes the password.. /// case MTH_SETPASSWORD: if ( ex.numParams() == 1 ) { const String* pwstr; if ( ex.getStringParam( 0, pwstr ) ) { if ( Core::config.retain_cleartext_passwords ) obj_->password_ = pwstr->value(); std::string temp; Clib::MD5_Encrypt( obj_->name_ + pwstr->value(), temp ); obj_->passwordhash_ = temp; //MD5 break; } else { return new BError( "Invalid parameter type" ); } } else return new BError( "account.SetPassword(newpass) requires a parameter." ); /// /// account.CheckPassword( password : string ) : checks if the password is valid /// case MTH_CHECKPASSWORD: if ( ex.numParams() == 1 ) { const String* pwstr; if ( ex.getStringParam( 0, pwstr ) ) { bool ret; string temp; Clib::MD5_Encrypt( obj_->name_ + pwstr->value(), temp );//MD5 ret = Clib::MD5_Compare( obj_->passwordhash_, temp ); result = new BLong( ret ); } else { return new BError( "Invalid parameter type" ); } } else return new BError( "account.CheckPassword(password) requires a parameter." ); break; /// /// account.SetAcctName( newname : string ) : changes the account name /// - deprecated in favor of: /// account.SetName( newname : string ) : changes the account name /// ACK, bug - since account data is saved immediately, /// a crash w/o save will result in a server that can't start /// because account names in accounts.txt will refer to the old name /// case MTH_SETNAME: //passed only new account name, and cleartext password is saved if ( ( ex.numParams() == 1 ) && Core::config.retain_cleartext_passwords ) { const String* nmstr; if ( ex.getStringParam( 0, nmstr ) ) { if ( nmstr->value().empty() ) return new BError( "Account name must not be empty." ); std::string temp; //passing the new name, and recalc name+pass hash (pass only hash is unchanged) obj_->name_ = nmstr->value(); Clib::MD5_Encrypt( obj_->name_ + obj_->password_, temp ); obj_->passwordhash_ = temp; //MD5 } else { return new BError( "Invalid parameter type" ); } } //passed new account name and password else if ( ex.numParams() == 2 ) { const String* nmstr; const String* pwstr; if ( ex.getStringParam( 0, nmstr ) && ex.getStringParam( 1, pwstr ) ) { if ( nmstr->value().empty() ) return new BError( "Account name must not be empty." ); obj_->name_ = nmstr->value(); //this is the same as the "setpassword" code above if ( Core::config.retain_cleartext_passwords ) obj_->password_ = pwstr->value(); std::string temp; Clib::MD5_Encrypt( obj_->name_ + pwstr->value(), temp ); obj_->passwordhash_ = temp; //MD5 } else { return new BError( "Invalid parameter type" ); } } else if ( ( ex.numParams() == 1 ) && !Core::config.retain_cleartext_passwords ) return new BError( "Usage: account.SetName(name,pass) if RetainCleartextPasswords is off." ); else return new BError( "account.SetName needs at least 1 parameter." ); break; /// /// account.GetProp( propname : string ) : gets a custom account property /// returns Error( "Property not found" ) if property does not exist. /// /// /// account.SetProp( propname : string, propval : packable ) : sets a custom account property /// /// /// account.EraseProp( propname : string ) : erases a custom account property. /// /// /// account.PropNames() : array of property names /// case MTH_GETPROP: case MTH_SETPROP: case MTH_ERASEPROP: case MTH_PROPNAMES: { bool changed = false; result = CallPropertyListMethod_id( obj_->props_, id, ex, changed ); if ( result && !changed ) return result; break; } case MTH_SETDEFAULTCMDLEVEL: { if ( ex.numParams() != 1 ) return new BError( "account.SetDefaultCmdLevel(int) requires a parameter." ); int cmdlevel; if ( !ex.getParam( 0, cmdlevel ) ) return new BError( "Invalid parameter type." ); else if ( cmdlevel >= static_cast<int>( Core::cmdlevels2.size() ) ) cmdlevel = static_cast<int>( Core::cmdlevels2.size() - 1 ); obj_->default_cmdlevel_ = char( cmdlevel ); break; } /// /// account.GetCharacter( index : 1..5 ) : retrieve a reference to a character belonging to this account. /// This reference may be used even if the character is offline. case MTH_GETCHARACTER: { if ( ex.numParams() != 1 ) return new BError( "account.GetCharacter(index) requires a parameter." ); int index; if ( !ex.getParam( 0, index, 1, Core::config.character_slots ) ) return NULL; Mobile::Character* chr = obj_->get_character( index - 1 ); if ( chr == NULL ) return new BError( "No such character on this account" ); return new Module::EOfflineCharacterRefObjImp( chr ); } /// /// account.DeleteCharacter( index : 1..5 ) : delete a character /// character to be deleted cannot be logged in. /// case MTH_DELETECHARACTER: { if ( ex.numParams() != 1 ) return new BError( "account.DeleteCharacter(index) requires a parameter." ); int index; if ( !ex.getParam( 0, index, 1, Core::config.character_slots ) ) return NULL; Mobile::Character* chr = obj_->get_character( index - 1 ); if ( chr == NULL ) return new BError( "No such character on this account" ); if ( chr->client != NULL || chr->logged_in ) return new BError( "That character is in use" ); if ( can_delete_character( chr, Core::DELETE_BY_SCRIPT ) ) { call_ondelete_scripts( chr ); delete_character( obj_.Ptr(), chr, index - 1 ); } else return new BError( "CanDelete blocks Character deletion." ); break; } /// /// account.Set_UO_Expansion( string ) : recognized values: ML, SE, AOS, LBR, T2A (default) /// this determines what flag is sent with packet 0xB9 during login. /// case MTH_SET_UO_EXPANSION: if ( ex.numParams() != 1 ) return new BError( "account.Set_UO_Expansion(string) requires a parameter." ); const String* expansion_str; if ( ex.getStringParam( 0, expansion_str ) ) { if ( expansion_str->value().empty() || ( expansion_str->value() == "HSA" ) || ( expansion_str->value() == "SA" ) || ( expansion_str->value() == "KR" ) || ( expansion_str->value() == "ML" ) || ( expansion_str->value() == "SE" ) || ( expansion_str->value() == "AOS" ) || ( expansion_str->value() == "LBR" ) || ( expansion_str->value() == "T2A" ) ) { obj_->uo_expansion_ = obj_->convert_uo_expansion( expansion_str->value() ); if ( obj_->active_character ) Core::send_feature_enable( obj_->active_character->client ); } else return new BError( "Invalid Parameter Value. Supported Values: \"\", T2A, LBR, AOS, SE, ML, KR, SA, HSA" ); } else return new BError( "Invalid Parameter Type" ); break; /// /// account.Delete() : delete this account /// case MTH_DELETE: if ( ex.numParams() == 0 ) { int _result = delete_account( obj_->name() ); if ( _result == -1 ) return new BError( "You must delete all Character first." ); else if ( _result == -2 ) // Should never happen ;o) return new BError( "Invalid Account Name." ); } else return new BError( "account.Delete() doesn't take parameters." ); break; /// /// account.Split( newacctname : string, index : 1..5 ) : create a new account and move character to it /// case MTH_SPLIT: if ( ex.numParams() == 2 ) { const String* acctname; int index; if ( ex.getStringParam( 0, acctname ) && ex.getParam( 1, index, 1, Core::config.character_slots ) ) { if ( acctname->value().empty() ) return new BError( "Account name must not be empty." ); if ( find_account( acctname->data() ) ) return new BError( "Account already exists." ); Mobile::Character* chr = obj_->get_character( index - 1 ); if ( chr == NULL ) return new BError( "No such character on this account." ); if ( chr->client != NULL || chr->logged_in ) return new BError( "That character is in use." ); Account* account = duplicate_account( obj_->name_, acctname->value() ); if ( account != NULL ) { obj_->clear_character( index - 1 ); chr->acct.set( account ); account->set_character( 0, chr ); } else return new BError( "Was impossible to create new Account." ); } else return new BError( "Invalid parameter type." ); } else return new BError( "account.Split requires two parameters." ); break; /// /// account.Move_Char( destacctname : string, index : 1..5 ) : move character from this account to destaccount /// case MTH_MOVE_CHAR: if ( ex.numParams() == 2 ) { const String* acctname; int index; if ( ex.getStringParam( 0, acctname ) && ex.getParam( 1, index, 1, Core::config.character_slots ) ) { if ( acctname->value().empty() ) return new BError( "Account name must not be empty." ); Account* account = find_account( acctname->data() ); if ( account == NULL ) return new BError( "Account doesn't exists." ); Mobile::Character* chr = obj_->get_character( index - 1 ); if ( chr == NULL ) return new BError( "No such character on this account." ); if ( chr->client != NULL || chr->logged_in ) return new BError( "That character is in use." ); int charid = account->getnextfreeslot(); if ( charid != -1 ) { obj_->clear_character( index - 1 ); chr->acct.set( account ); account->set_character( charid - 1, chr ); } else return new BError( "Account is full." ); } else return new BError( "Invalid parameter type." ); } else return new BError( "account.Move_Char requires two parameters." ); break; case MTH_ADD_CHARACTER: { int index; if ( !ex.getParam( 0, index, 0, Core::config.character_slots ) ) return new BError( "Account.AddCharacter() requires one parameter." ); if ( index <= 0 ) { index = obj_->getnextfreeslot(); if ( index == -1 ) return new BError( "Account has no free character slots." ); } // We take in 1-5 to match account.GetCharacter() // Internally it uses it as 0-4 index--; if ( obj_->get_character( index ) ) { return new BError( "That character slot is already in use." ); } result = new BLong( index + 1 ); Account* acct = find_account( obj_->name_.c_str() ); if (acct == NULL) { return new BError("Account doesn't exist."); } Core::createchar2( acct, unsigned( index ) ); break; } default: return NULL; } // if any of the methods hit & worked, we'll come here if ( Core::config.account_save == -1 ) write_account_data(); else accounts_txt_dirty = true; return result ? result : new BLong( 1 ); }