void handle_ef_seed( Client *client, PKTIN_EF *msg )
{
	VersionDetailStruct detail;
	detail.major=cfBEu32(msg->ver_Major);
	detail.minor=cfBEu32(msg->ver_Minor);
	detail.rev=cfBEu32(msg->ver_Revision);
	detail.patch=cfBEu32(msg->ver_Patch);
	client->setversiondetail(detail);
    if (client->compareVersion(CLIENT_VER_7000))
        client->setClientType(CLIENTTYPE_7000);
	else if (client->compareVersion(CLIENT_VER_60142))
		client->setClientType(CLIENTTYPE_60142);
	else if (client->compareVersion(CLIENT_VER_6017)) //Grid-loc support
		client->setClientType(CLIENTTYPE_6017);
    else if (client->compareVersion(CLIENT_VER_5020))
		client->setClientType(CLIENTTYPE_5020);
	else if (client->compareVersion(CLIENT_VER_5000))
		client->setClientType(CLIENTTYPE_5000);
    else if (client->compareVersion(CLIENT_VER_4070))
        client->setClientType(CLIENTTYPE_4070);
    else if (client->compareVersion(CLIENT_VER_4000))
        client->setClientType(CLIENTTYPE_4000);

	// detail->patch is since 5.0.7 always numeric, so no need to make it complicated
	OSTRINGSTREAM os;
	os << detail.major << "." << detail.minor << "." << detail.rev << "." << detail.patch;
	client->setversion(OSTRINGSTREAM_STR(os));
}
void handle_e1_clienttype( Client *client, PKTIN_E1 *msg )
{
	switch (cfBEu32(msg->clienttype))
	{
	case PKTIN_E1::CLIENTTYPE_KR:
		client->setClientType(CLIENTTYPE_UOKR);
		break;
	case PKTIN_E1::CLIENTTYPE_SA:
		client->setClientType(CLIENTTYPE_UOSA);
		break;
	default:
		printf( "Unknown client type send with packet 0xE1 : 0x%lx\n",cfBEu32(msg->clienttype));
		break;
	}
}
void handle_allnames( Client *client, PKTBI_98_IN *msg )
{

	u32 serial = cfBEu32( msg->serial );
	Character *the_mob = find_character( serial );
	if (the_mob != NULL)
	{
		if (!client->chr->is_visible_to_me(the_mob)) {
			return;
		}
		if (pol_distance(client->chr->x, client->chr->y, the_mob->x, the_mob->y) > 20) {
			return;
		}

		PKTBI_98_OUT allnames;
		allnames.msgtype = PKTBI_98_OUT_ID;
		allnames.msglen = ctBEu16(0x25);  // 0x25 = 37. Static Length.
		allnames.serial = the_mob->serial_ext;
		strzcpy( allnames.name, the_mob->name().c_str(), sizeof allnames.name );
		transmit( client, &allnames, sizeof allnames );

	}
	else
	{
		return;
	}
}
Exemple #4
0
void srequest( Network::Client* client, PKTIN_34* msg )
{
  u32 serial = cfBEu32( msg->serial2 );

  if ( msg->stattype == STATTYPE_STATWINDOW )
  {
    if ( client->chr->serial == serial )
      statrequest( client, serial );
    else
    {
      Mobile::Character* bob = find_character( serial );
      if ( bob == NULL )
        return;
      if ( !client->chr->is_concealed_from_me( bob ) && client->chr->is_visible_to_me( bob ) )
      {
        if ( pol_distance( client->chr->x, client->chr->y, bob->x, bob->y ) < 20 )
          statrequest( client, serial );
      }
      if ( client->chr->has_party() )
        client->chr->party()->send_stat_to( client->chr, bob );
    }
  }
  else if ( msg->stattype == STATTYPE_SKILLWINDOW )
    skillrequest( client, serial );
}
Exemple #5
0
void handle_delete_character( Network::Client* client, PKTIN_83* msg )
{
  u32 charidx = cfBEu32( msg->charidx );

  if ( ( charidx >= Plib::systemstate.config.character_slots ) || ( client->acct == nullptr ) ||
       ( client->acct->get_character( charidx ) == nullptr ) )
  {
    send_login_error( client, LOGIN_ERROR_MISC );
    client->Disconnect();
    return;
  }

  Accounts::Account* acct = client->acct;
  Mobile::Character* chr = acct->get_character( charidx );
  if ( chr->client != nullptr || ( !Plib::systemstate.config.allow_multi_clients_per_account &&
                                   acct->has_active_characters() ) )
  {
    send_login_error( client, LOGIN_ERROR_OTHER_CHAR_INUSE );
    client->Disconnect();
    return;
  }

  if ( can_delete_character( chr, DELETE_BY_PLAYER ) )
  {
    call_ondelete_scripts( chr );
    delete_character( acct, chr, charidx );
  }

  send_start( client );
}
Exemple #6
0
void NoLosCheckedTargetCursor::on_target_cursor( Mobile::Character* chr, PKTBI_6C* msgin )
{
  if ( msgin == NULL )
  {
    ( *func )( chr, NULL );
    return;
  }

  u32 selected_serial = cfBEu32( msgin->selected_serial );

  UObject* uobj = find_toplevel_object( selected_serial );
  // FIXME inefficient, but neither works well by itself.
  bool additlegal = false;
  if ( uobj == NULL )
    uobj = find_legal_item( chr, selected_serial, &additlegal );

  if ( uobj == NULL )
    uobj = system_find_multi( selected_serial );

  if ( uobj == NULL )
  {
    if ( chr->client != NULL ) send_sysmessage( chr->client, "What you selected does not seem to exist." );
    if ( inform_on_cancel_ )
      ( *func )( chr, NULL );
    return;
  }

  ( *func )( chr, uobj );
}
Exemple #7
0
void handle_singleclick(Network::Client* client, PKTIN_09* msg)
{
  u32 serial = cfBEu32( msg->serial );
  if (client && client->chr)
    singleclick(client, serial);
  // TODO: report if someone tries to use singleclick without a connected char (should have been blocked)
}
Exemple #8
0
void TargetCursor::handle_target_cursor( Mobile::Character* chr, PKTBI_6C* msg )
{
  if ( msg->selected_serial != 0 )   // targetted something
  {

    if ( chr->dead() )            // but is dead
    {
      if ( chr->client != NULL ) send_sysmessage( chr->client, "I am dead and cannot do that." );
      cancel( chr );
      return;
    }

    if ( ( chr->frozen() || chr->paralyzed() ) && !chr->setting_enabled( "freemove" ) )
    {
      if ( chr->client != NULL )
      {
        if ( chr->frozen() )
          private_say_above( chr, chr, "I am frozen and cannot do that." );
        else if ( chr->paralyzed() )
          private_say_above( chr, chr, "I am paralyzed and cannot do that." );
      }
      cancel( chr );
      return;
    }

    u32 selected_serial = cfBEu32( msg->selected_serial );
    UObject* obj = system_find_object( selected_serial );
    if ( obj != NULL && obj->script_isa( POLCLASS_MOBILE ) &&
         !obj->script_isa( POLCLASS_NPC ) )
    {
      Mobile::Character* targeted = find_character( selected_serial );
      // check for when char is not logged on
      if ( targeted != NULL )
      {
        if ( !chr->is_visible_to_me( targeted ) )
        {
          cancel( chr );
          return;
        }

        if ( msg->cursor_type == 1 )
        {
          if ( ( JusticeRegion::RunNoCombatCheck( chr->client ) == true )
               || ( JusticeRegion::RunNoCombatCheck( targeted->client ) == true ) )
          {
            send_sysmessage( chr->client, "Combat is not allowed in this area." );
            cancel( chr );
            return;
          }
        }
      }
    }
  }

  if ( msg->x != 0xffff || msg->selected_serial != 0 )
    on_target_cursor( chr, msg );
  else
    cancel( chr );
}
Exemple #9
0
void NoLosCharacterCursor::on_target_cursor( Mobile::Character* targetter, PKTBI_6C* msgin )
{
  if ( msgin == NULL )
    return;
  u32 selected_serial = cfBEu32( msgin->selected_serial );
  Mobile::Character* chr = find_character( selected_serial );
  if ( chr != NULL )
    ( *func )( targetter, chr );
}
Exemple #10
0
void handle_se_object_list( Client* client, PKTBI_D6_IN* msgin )
{
	UObject* obj = NULL;
	int length=cfBEu16(msgin->msglen)-3;
	if ( length < 0 || (length%4) != 0 )
		return;
	int count = length/4;
	
	for( int i = 0; i < count; ++i )
	{
		obj = system_find_object(cfBEu32( msgin->serials[i].serial ));
		if (obj != NULL)
			SendAOSTooltip(client,obj);
	}
}
Exemple #11
0
void handle_rename_char( Client* client, PKTIN_75* msg )
{
    Character* chr = find_character( cfBEu32( msg->serial ));
    if (chr != NULL)
    {
        if (client->chr->can_rename( chr ))
        {
            msg->name[ sizeof msg->name-1 ] = '\0';
            // check for legal characters
			for( char* p = msg->name; *p; p++ )
			{
				// only allow: a-z, A-Z & spaces
				if ( *p != ' ' && !isalpha(*p) )
				{
					char buffer[512];
					sprintf(buffer, "Client #%lu (account %s) attempted an invalid rename (packet 0x%2.02x):",
									client->instance_,
									(client->acct != NULL) ? client->acct->name() : "unknown",
									msg->msgtype);
					cout << buffer << endl;
					fdump( stdout, msg->name, static_cast<int>(strlen(msg->name)) );

					if (logfile)
					{
						Log("%s\n", buffer);
						fdump( logfile, msg->name, static_cast<int>(strlen(msg->name)) );
					}

					*p = '\0';
					send_sysmessage( client, "Invalid name!" );
					return; //dave 12/26 if invalid name, do not apply to chr!
				}
			}
            chr->setname( msg->name );
        }
        else
        {
            send_sysmessage( client, "I can't rename that." );
        }
    }
    else
    {
        send_sysmessage( client, "I can't find that." );
    }
}
Exemple #12
0
void NoLosUObjectCursor::on_target_cursor( Mobile::Character* targetter, PKTBI_6C* msgin )
{
  if ( msgin == NULL )
  {
    ( *func )( targetter, NULL );
    return;
  }
  u32 selected_serial = cfBEu32( msgin->selected_serial );

  UObject* obj = system_find_object( selected_serial );
  if ( obj )
  {
    ( *func )( targetter, obj );
  }
  else if ( inform_on_cancel_ )
  {
    ( *func )( targetter, NULL );
  }
}
Exemple #13
0
void ObjectHash::Reap()
{
  // this is called every 2 seconds (approximately)
  // iterate through enough of the object hash that it will be swept entirely once every 30 minutes
  // 2 minutes = 120 seconds = 60 reap calls per sweep
  // 30 minutes = 1800 seconds = 900 reap calls per sweep

  // first, figure out how many objects to check:
  hs::size_type count = hash.size();
  if ( count == 0 )
    return;
  hs::size_type count_this = count / 60;
  if ( count_this < 1 )
    count_this = 1;
  if ( reap_iterator == hash.end() )
    reap_iterator = hash.begin();

  while ( count_this-- )
  {
    UObject* obj = ( *reap_iterator ).second.get();

    // We want the objecthash to be the holder of the last reference to an
    // object when it is deleted - hence the ref_counted_count() check.
    if ( obj->orphan() && obj->ref_counted_count() == 1 )
    {
      dirty_deleted.insert( cfBEu32( obj->serial_ext ) );
      hash.erase( reap_iterator++ );
    }
    else
      ++reap_iterator;

    if ( reap_iterator == hash.end() )
    {
      reap_iterator = hash.begin();
      if ( reap_iterator == hash.end() )
        break;
    }
  }
}
Exemple #14
0
void handle_D9( Network::Client* client, PKTIN_D9* msg )
{
  PKTIN_D9 _msg;  // got crashes here under *nix -> modify a new local instance
  // Transform Little-Endian <-> Big-Endian
  _msg.instance = cfBEu32( msg->instance );              // Unique Instance ID of UO
  _msg.os_major = cfBEu32( msg->os_major );              // OS Major
  _msg.os_minor = cfBEu32( msg->os_minor );              // OS Minor
  _msg.os_revision = cfBEu32( msg->os_revision );        // OS Revision
  _msg.cpu_family = cfBEu32( msg->cpu_family );          // CPU Family
  _msg.cpu_model = cfBEu32( msg->cpu_model );            // CPU Model
  _msg.cpu_clockspeed = cfBEu32( msg->cpu_clockspeed );  // CPU Clock Speed [Mhz]
  _msg.memory = cfBEu32( msg->memory );                  // Memory [MB]
  _msg.screen_width = cfBEu32( msg->screen_width );      // Screen Width
  _msg.screen_height = cfBEu32( msg->screen_height );    // Screen Height
  _msg.screen_depth = cfBEu32( msg->screen_depth );      // Screen Depth [Bit]
  _msg.directx_major = cfBEu16( msg->directx_major );    // DirectX Major
  _msg.directx_minor = cfBEu16( msg->directx_minor );    // DirectX Minor

  for ( unsigned i = 0; i < sizeof( msg->video_description ) / sizeof( msg->video_description[0] );
        ++i )
    _msg.video_description[i] =
        cfBEu16( msg->video_description[i] );  // Video Card Description [wide-character]

  _msg.video_vendor = cfBEu32( msg->video_vendor );  // Video Card Vendor ID
  _msg.video_device = cfBEu32( msg->video_device );  // Video Card Device ID
  _msg.video_memory = cfBEu32( msg->video_memory );  // Video Card Memory [MB]

  for ( unsigned i = 0; i < sizeof( msg->langcode ) / sizeof( msg->langcode[0] ); ++i )
    _msg.langcode[i] = cfBEu16( msg->langcode[i] );  // Language Code [wide-character]

  client->setclientinfo( &_msg );
}
Exemple #15
0
void doubleclick( Network::Client* client, PKTIN_06* msg )
{
  u32 serial = cfBEu32( msg->serial );
  u32 paperdoll_macro_flag = serial & 0x80000000Lu;
  serial &= ~0x80000000Lu;  // keypress versus doubleclick switch?

  // the find_character would find this, but most of the time it's your own paperdoll.
  // this is special-cased for two reasons:
  //    1) it's commonly done
  //    2) ghosts can doubleclick ONLY their paperdoll.
  if ( serial == client->chr->serial )
  {
    if ( !paperdoll_macro_flag )
    {
      ScriptDef sd;
      sd.quickconfig( "scripts/misc/dblclickself.ecl" );
      if ( sd.exists() )
      {
        ref_ptr<Bscript::EScriptProgram> prog;
        prog = find_script2( sd, false, Plib::systemstate.config.cache_interactive_scripts );
        if ( prog.get() != nullptr && client->chr->start_script( prog.get(), false ) )
        {
          return;
        }
      }
    }
    send_paperdoll( client, client->chr );
    return;
  }

  if ( client->chr->dblclick_wait() > read_gameclock() )
  {
    private_say_above( client->chr, client->chr, "You must wait to use something again." );
    return;
  }
  else
    client->chr->dblclick_wait( read_gameclock() + settingsManager.ssopt.dblclick_wait );

  if ( IsCharacter( serial ) )
  {
    if ( client->chr->dead() )
      return;
    Mobile::Character* chr = find_character( serial );
    if ( !chr )
      return;

    if ( chr->isa( UOBJ_CLASS::CLASS_NPC ) )
    {
      Mobile::NPC* npc = static_cast<Mobile::NPC*>( chr );
      if ( npc->can_accept_event( EVID_DOUBLECLICKED ) )
      {
        npc->send_event( new Module::SourcedEvent( EVID_DOUBLECLICKED, client->chr ) );
        return;
      }
    }

    bool script_ran = false;
    ScriptDef sd;
    sd.quickconfig( "scripts/misc/dblclickother.ecl" );
    if ( sd.exists() )
    {
      ref_ptr<Bscript::EScriptProgram> prog;
      prog = find_script2( sd, false, Plib::systemstate.config.cache_interactive_scripts );
      if ( prog.get() != nullptr )
        script_ran =
            client->chr->start_script( prog.get(), false, new Module::ECharacterRefObjImp( chr ) );
    }
    if ( !script_ran && inrange( client->chr, chr ) )
    {
      // MuadDib Changed from a large if || || || to switch case. 1/4/2007
      switch ( chr->graphic )
      {
      case UOBJ_HUMAN_MALE:
      case UOBJ_HUMAN_FEMALE:
      case UOBJ_HUMAN_MALE_GHOST:
      case UOBJ_HUMAN_FEMALE_GHOST:
      case UOBJ_ELF_MALE:
      case UOBJ_ELF_FEMALE:
      case UOBJ_ELF_MALE_GHOST:
      case UOBJ_ELF_FEMALE_GHOST:
      case UOBJ_GARGOYLE_MALE:
      case UOBJ_GARGOYLE_FEMALE:
      case UOBJ_GARGOYLE_MALE_GHOST:
      case UOBJ_GARGOYLE_FEMALE_GHOST:
      case UOBJ_GAMEMASTER:
      case 0x3de:
      case 0x3df:
      case 0x3e2:
        send_paperdoll( client, chr );
        break;
      }
    }
    return;
  }
  else  // doubleclicked an item
  {
    // next, search worn items, items in the backpack, and items in the world.
    Items::Item* item = find_legal_item( client->chr, serial );

    // next, check people's backpacks. (don't recurse down)
    //    (not done yet)

    if ( item != nullptr )
    {
      const Items::ItemDesc& id = item->itemdesc();

      if ( !id.ghosts_can_use && client->chr->dead() )
      {
        private_say_above( client->chr, client->chr, "I am dead and cannot do that." );
        return;
      }
      if ( !id.can_use_while_frozen && client->chr->frozen() )
      {
        private_say_above( client->chr, client->chr, "I am frozen and cannot do that." );
        return;
      }
      if ( !id.can_use_while_paralyzed && client->chr->paralyzed() )
      {
        private_say_above( client->chr, client->chr, "I am paralyzed and cannot do that." );
        return;
      }

      unsigned short dst = pol_distance( client->chr, item );
      if ( dst > id.doubleclick_range && !client->chr->can_dblclickany() )
      {
        private_say_above( client->chr, item, "That is too far away." );
        return;
      }
      UObject* obj = item->toplevel_owner();
      obj = obj->self_as_owner();
      if ( id.use_requires_los && !client->chr->realm->has_los( *client->chr, *obj ) )  // DAVE
                                                                                        // 11/24
      {
        private_say_above( client->chr, item, "I can't see that." );
        return;
      }

      ScriptDef sd;
      sd.quickconfig( "scripts/misc/dblclickitem.ecl" );
      if ( sd.exists() )
      {
        ref_ptr<Bscript::EScriptProgram> prog;
        prog = find_script2( sd, false, Plib::systemstate.config.cache_interactive_scripts );
        if ( prog.get() != nullptr )
          client->chr->start_script( prog.get(), false, new Module::EItemRefObjImp( item ) );
      }

      item->double_click( client );
      return;
    }

    // allow looking into containers being traded
    if ( client->chr->is_trading() )
    {
      UContainer* cont = client->chr->trade_container()->find_container( serial );
      if ( cont != nullptr )
      {
        cont->builtin_on_use( client );
        if ( !cont->locked() )
        {
          if ( client->chr->trading_with->client != nullptr )
            cont->builtin_on_use( client->chr->trading_with->client );
        }
        return;
      }
    }
  }
}
Exemple #16
0
void equip_item( Client *client, PKTIN_13 *msg )
{
	u32 serial = cfBEu32( msg->serial );
	u8 layer = msg->layer;
	u32 equip_on_serial = cfBEu32( msg->equipped_on );

	if ((layer > HIGHEST_LAYER) || (layer == 0) || client->chr->dead())
	{
		send_item_move_failure( client, MOVE_ITEM_FAILURE_ILLEGAL_EQUIP );
		return;
	}
	
	Item *item = client->chr->gotten_item;

	if (item == NULL)
	{
		Log( "Character %08lX tried to equip item %08lx, which did not exist in gotten_items.\n",
			 client->chr->serial, serial );
		send_item_move_failure( client, MOVE_ITEM_FAILURE_ILLEGAL_EQUIP ); // 5
		return;
	}

    if (item->serial != serial)
	{
		Log( "Character %08lX tried to equip item %08lx, but had gotten item %08lX\n",
			 client->chr->serial, 
			 serial,
			 item->serial);
		send_item_move_failure( client, MOVE_ITEM_FAILURE_ILLEGAL_EQUIP ); // 5
		item->gotten_by = NULL;
		return;
	}

	ItemRef itemref(item);

	item->layer = item->tile_layer;
	client->chr->gotten_item->inuse(false);
	item->is_gotten(false);
	item->gotten_by = NULL;
	client->chr->gotten_item = NULL;

    Character* equip_on = NULL;
    if (equip_on_serial == client->chr->serial)
    {
        equip_on = client->chr;
    }
    else
    {
        equip_on = find_character( equip_on_serial );
        if (equip_on == NULL ||
            !client->chr->can_clothe( equip_on ))
        {
		    send_item_move_failure( client, MOVE_ITEM_FAILURE_ILLEGAL_EQUIP );

		    undo_get_item( client->chr, item );
            return;		
        }
    }

	if (equip_on->layer_is_equipped( item->tile_layer ))
	{
		// it appears the client already checks for this, so this code hasn't been exercised.
		// we'll assume client mouse holds on to object
        // 3D Client doesn't check for this!
		send_item_move_failure( client, MOVE_ITEM_FAILURE_ALREADY_WORN );

        undo_get_item( client->chr, item ); //added 11/01/03 for 3d client
		return;
	}

    if (!equip_on->strong_enough_to_equip( item ))
    {
		send_item_move_failure( client, MOVE_ITEM_FAILURE_ILLEGAL_EQUIP );
		// the client now puts the item back where it was before.

		// return the item to wherever it was. (?)
		undo_get_item( client->chr, item );
        if (client->chr == equip_on)
        {
            send_sysmessage( client, "You are not strong enough to use that." );
        }
        else
        {
            send_sysmessage( client, "Insufficient strength to equip that." );
        }
        return;		
    }

    if (!equip_on->equippable( item ) ||
        !item->check_equiptest_scripts( equip_on ) ||
        !item->check_equip_script( equip_on, false ))
    {
		send_item_move_failure( client, MOVE_ITEM_FAILURE_ILLEGAL_EQUIP );
		if(item->orphan())
		{
			return;
		}
		undo_get_item( client->chr, item );
		return;		
    }

	if(item->orphan())
	{
		return;
	}
    
	equip_on->equip( item );
	send_wornitem_to_inrange( equip_on, item );
}
Exemple #17
0
void handle_msg_BF( Client* client, PKTBI_BF* msg )
	{
	UObject* obj = NULL;
	UMulti* multi = NULL;
	UHouse* house = NULL;
	switch(cfBEu16(msg->subcmd))
		{
		case PKTBI_BF::TYPE_CLIENT_LANGUAGE:
			client->chr->uclang = strlower(msg->client_lang);
			break;
		case PKTBI_BF::TYPE_REQ_FULL_CUSTOM_HOUSE:
			if( (client->UOExpansionFlag & AOS) == 0 )
				return;
			multi = system_find_multi(cfBEu32(msg->reqfullcustomhouse.house_serial));
			if(multi != NULL)
				{
				house = multi->as_house();
				if(house != NULL)
					{
					if(client->UOExpansionFlag & AOS)
						{
						send_object_cache(client, (UObject*)(house));
						}
					//consider sending working design to certain players, to assist building, or GM help
					CustomHousesSendFull( house, client, HOUSE_DESIGN_CURRENT );
					}
				}
			break;
		case PKTBI_BF::TYPE_OBJECT_CACHE:
			if( (client->UOExpansionFlag & AOS) == 0)
				return;
			obj = system_find_object(cfBEu32(msg->objectcache.serial));
			if(obj != NULL)
				{
				SendAOSTooltip(client,obj);
				}
			break;
		case PKTBI_BF::TYPE_SESPAM:
			return;
			break;
		case PKTBI_BF::TYPE_SPELL_SELECT:
			do_cast(client, cfBEu16(msg->spellselect.selected_spell) );
			break;
		case PKTBI_BF::TYPE_CHARACTER_RACE_CHANGER:
			character_race_changer_handler( client, msg );
			break;
		case PKTBI_BF::TYPE_PARTY_SYSTEM:
			party_cmd_handler( client, msg );
			break;
		case PKTBI_BF::TYPE_EXTENDED_STATS_IN:
			ext_stats_in(client, msg);
			break;
		case PKTBI_BF::TYPE_CLOSED_STATUS_GUMP:
			return;
			break;
		case PKTBI_BF::TYPE_SCREEN_SIZE:
			return;
			break;
		case PKTBI_BF::TYPE_TOGGLE_FLYING:
			if (client->chr->race==RACE_GARGOYLE)
				{
				// FIXME: add checks if its possible to stand with new movemode
				client->chr->movemode = (MOVEMODE)(client->chr->movemode ^ MOVEMODE_FLY);
				send_move_mobile_to_nearby_cansee( client->chr );
				send_goxyz( client, client->chr );
				}
			break;
		case PKTBI_BF::TYPE_CLIENTTYPE:
			client->UOExpansionFlagClient = ctBEu32( msg->clienttype.clientflag );
			break;
		default:
			handle_unknown_packet( client );
		}
	}