예제 #1
0
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;
    }
}
예제 #2
0
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;
}
예제 #3
0
	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;
	  }
	}
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;
    }
}
예제 #5
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;
}
예제 #6
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" );
	}
}
예제 #7
0
	///
	/// [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 );
	}