예제 #1
0
SOCKET open_listen_socket( unsigned short port )
{
	int res;
	SOCKET sck;

	sck = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
	if (sck < 0)
	{
		throw runtime_error( "Unable to create listening socket" );
		return -1;
	}

    apply_socket_options( sck );

#ifndef WIN32
	int reuse_opt = 1;
	res = setsockopt( sck, SOL_SOCKET, SO_REUSEADDR, (const char *) &reuse_opt, sizeof(reuse_opt) );
	if (res < 0)
	{
		throw runtime_error( "Unable to setsockopt (SO_REUSEADDR) on listening socket, res = " + decint(res) );
	}
#endif

#define DISABLE_NAGLE_ALGORITHM 0
#if DISABLE_NAGLE_ALGORITHM
    int tcp_nodelay = -1;
    res = setsockopt( sck, IPPROTO_TCP, TCP_NODELAY, (const char *) &tcp_nodelay, sizeof(tcp_nodelay) );
    if (res < 0)
    {
		cout << "Unable to setsockopt (TCP_NODELAY) on listening socket, res=" << res << endl;
		return -1;
    }
#endif

	struct sockaddr_in connection;
	connection.sin_family = AF_INET;
	connection.sin_addr.s_addr = INADDR_ANY;
	connection.sin_port = ctBEu16( port );


	res = bind( sck, (struct sockaddr *) &connection, sizeof connection );
	if ( res < 0 )
	{
		// Aug. 16, 2006. Austin
		//   Added the port number that failed.
		string tmp_error = "Unable to bind listening socket. Port("+decint(port)+") Res="+decint(res);
		throw runtime_error(tmp_error);
	}

	res = listen( sck, SOMAXCONN );
	if (res < 0)
	{
		throw runtime_error( "Listen failed, res=" + decint(res) );
	}

	return sck;
}
예제 #2
0
bool load_realms()
{
	//string realm_dir = "realm/";
	Realm* temprealm;
	int realm_counter = 0;
	for( DirList dl( config.realm_data_path.c_str() ); !dl.at_end(); dl.next() )
	{
		string realm_name = dl.name();
		if (realm_name[0] == '.') 
			continue;

		passert_r( Realms->size() < MAX_NUMER_REALMS,
			"You can't use more than " + decint(MAX_NUMER_REALMS) + " realms");

		cout << "Loading Realm " << realm_name << "." << endl;

		temprealm = new Realm( realm_name, config.realm_data_path+realm_name );
		Realms->push_back( temprealm );
		++realm_counter;

		//To-Fix - Nasty kludge assuming 'britannia' is the default realm
		//May want to make this configurable in later core releases.
		if( realm_name == string("britannia") )
			main_realm = temprealm;
	}
//	main_realm = new DummyRealm();
	baserealm_count = realm_counter;
	shadowrealm_count = 0;
	if (realm_counter > 0)
		return true;
	else
		return false;
}
예제 #3
0
	SocketListener::SocketListener( unsigned short port, Socket::option opt ) :
	  _listen_sck()
	{
	  _listen_sck.set_options( opt );

	  if( !_listen_sck.listen( port ) )
		throw runtime_error( "Unable to open listen port " + decint( port ) );
	}
예제 #4
0
void uo_client_listener_thread( void* arg )
{
    UoClientListener* ls = reinterpret_cast<UoClientListener*>(arg);

	atomic_cout( "Listening for UO clients on port " + decint(ls->port) 
		+ " (encryption: " + decint(ls->encryption.eType) + "," + hexint(ls->encryption.uiKey1) + "," + hexint(ls->encryption.uiKey2) + ")");

    SocketListener SL( ls->port, Socket::option(Socket::nonblocking|Socket::reuseaddr) );
    while (!exit_signalled)
    {
        if (SL.GetConnection( 5 ))
        {
            // create an appropriate Client object

            SocketClientThread* thread = new UoClientThread( ls, SL );
            thread->start();
        }
    }
}
예제 #5
0
void apply_socket_options( SOCKET sck )
{
#ifdef _WIN32
	u_long nonblocking = 1;
	int res = ioctlsocket( sck, FIONBIO, &nonblocking );
#else
	int flags = fcntl( sck, F_GETFL );
    flags |= O_NONBLOCK;
    int res = fcntl( sck, F_SETFL, flags );
#endif
	if (res < 0)
	{
		throw runtime_error( "Unable to set socket to nonblocking mode, res=" + decint(res) );
	}
}
예제 #6
0
BObjectImp* GetGlobals( const UOExecutor* uoexec )
{
	BDictionary* dict = new BDictionary;

	BObjectRefVec::const_iterator itr = uoexec->Globals2.begin(), end=uoexec->Globals2.end();
	
	for( unsigned idx = 0; itr != end; ++itr,++idx )
	{
		const BObjectRef obref( (*itr)->impref().copy() );
		
		if (uoexec->prog()->globalvarnames.size() > idx)
			dict->addMember( uoexec->prog()->globalvarnames[idx].c_str(), obref );
		else
			dict->addMember( decint( idx ).c_str(), obref );
	}
	return dict;
}
예제 #7
0
	SocketListener::SocketListener( unsigned short port ) :
	  _listen_sck()
	{
	  if( !_listen_sck.listen( port ) )
		throw runtime_error( "Unable to open listen port " + decint( port ) );
	}
예제 #8
0
/* Note: This function is ONLY used from Executor::read(). */
int EScriptProgram::_readToken(Token& token, unsigned position) const
{
    StoredToken st;
    tokens.atGet1( position, st );
    // StoredToken& st = tokens[position];

    token.module = (ModuleID) st.module;
    token.id = static_cast<BTokenId>(st.id);
    token.type = static_cast<BTokenType>(st.type);
    token.lval = st.offset;

    token.nulStr();

    // FIXME: USED to set lval to 0 for TYP_FUNC.  Not sure if needed anymore.
    // FIXME: Doesn't seem to be, but must be sure before removal
    switch( st.id )
    {
        case INS_CASEJMP:
            if (st.offset >= symbols.length())
            {
                throw runtime_error( "Symbol offset of " + decint(st.offset) + " exceeds symbol store length of " + decint(symbols.length()) + " at PC=" + decint(position));
            }
            token.dataptr = reinterpret_cast<const unsigned char*>(symbols.array()+st.offset);
            return 0;
        case TOK_LONG:
            if (st.offset >= symbols.length())
            {
                throw runtime_error( "Symbol offset of " + decint(st.offset) + " exceeds symbol store length of " + decint(symbols.length()) + " at PC=" + decint(position));
            }
            token.lval = * (long *) (symbols.array()+st.offset);
            return 0;
        case TOK_DOUBLE:
            if (st.offset >= symbols.length())
            {
                throw runtime_error( "Symbol offset of " + decint(st.offset) + " exceeds symbol store length of " + decint(symbols.length()) + " at PC=" + decint(position));
            }
            token.dval = * (double *) (symbols.array()+st.offset);
            return 0;

        case CTRL_STATEMENTBEGIN:
            if (st.offset) 
            {
                if (st.offset >= symbols.length())
                {
                    throw runtime_error( "Symbol offset of " + decint(st.offset) + " exceeds symbol store length of " + decint(symbols.length()) + " at PC=" + decint(position));
                    return -1;
                }
                DebugToken *dt = (DebugToken *) (symbols.array()+st.offset);
                token.sourceFile = dt->sourceFile;
                token.lval = dt->offset;

                if (dt->strOffset >= symbols.length())
                {
                    throw runtime_error( "Symbol offset of " + decint(dt->strOffset) + " exceeds symbol store length of " + decint(symbols.length()) + " at PC=" + decint(position));
                    return -1;
                }
                if (dt->strOffset) token.setStr(symbols.array() + dt->strOffset);
            }
            return 0;

        case INS_INITFOREACH:
        case INS_STEPFOREACH:
        case INS_INITFOR:
        case INS_NEXTFOR:
        case TOK_GLOBALVAR:
        case TOK_LOCALVAR:
        case CTRL_JSR_USERFUNC:
        case CTRL_LEAVE_BLOCK:
        case TOK_ARRAY_SUBSCRIPT:
        case RSV_JMPIFFALSE:
        case RSV_JMPIFTRUE:
        case RSV_GOTO:
        case RSV_LOCAL:
        case RSV_GLOBAL:
        case INS_ASSIGN_GLOBALVAR:
        case INS_ASSIGN_LOCALVAR:
        case INS_GET_MEMBER_ID:
        case INS_SET_MEMBER_ID:
        case INS_SET_MEMBER_ID_CONSUME:
        case INS_CALL_METHOD_ID:
		    token.lval = st.offset;
		    return 0;

        case INS_CALL_METHOD:
        case TOK_FUNC:
        case TOK_USERFUNC:
            token.lval = st.type;
            token.type = (st.id == TOK_FUNC) ? TYP_FUNC : TYP_USERFUNC;
            if (st.offset)
            {
                if (st.offset >= symbols.length())
                {
                    throw runtime_error( "Symbol offset of " + decint(st.offset) + " exceeds symbol store length of " + decint(symbols.length()) + " at PC=" + decint(position));
                }
                token.setStr(symbols.array()+st.offset);
            }
            else if (token.type == TYP_FUNC)
            {
                FunctionalityModule* modl = modules[token.module];
                const ModuleFunction* modfunc;

                // executor only:
                modfunc = modl->functions.at( token.lval );

                token.setStr( modfunc->name.c_str() );
            }
            return 0;

        default:
          if (st.offset) 
          {
              if (st.offset >= symbols.length())
              {
                  throw runtime_error( "Symbol offset of " + decint(st.offset) + " exceeds symbol store length of " + decint(symbols.length()) + " at PC=" + decint(position));
              }
              token.setStr(symbols.array()+st.offset);
          }
          return 0;
    }
}
예제 #9
0
Item* Item::create( const ItemDesc& id, u32 serial)
{
	unsigned short objtype = id.objtype;
	unsigned short graphic = id.graphic;
	
	Item* item;
	// FIXME looks like a place for a bunch of function pointers if I ever saw one.
	if (id.type == ItemDesc::DOORDESC)
	{
		item = new UDoor( static_cast<const DoorDesc&>(id) );
	}
	else if (id.type == ItemDesc::BOATDESC)
	{
		// still created with create_multi
		return NULL;
	}
	else if (id.type == ItemDesc::HOUSEDESC)
	{
		// still created with create_multi
		return NULL;
	}
	else if ( (objtype >= spell_scroll_objtype_limits[0][0] &&
			   objtype <= spell_scroll_objtype_limits[0][1]) ||
			  (objtype >= spell_scroll_objtype_limits[1][0] &&
			   objtype <= spell_scroll_objtype_limits[1][1]) ||
			  (objtype >= spell_scroll_objtype_limits[2][0] &&
			   objtype <= spell_scroll_objtype_limits[2][1]) )
	{
		item = new USpellScroll( id );
	}
	else if (objtype == UOBJ_CORPSE) // ITEMDESCTODO make new ItemDesc type
	{
		item = new UCorpse( static_cast<const ContainerDesc&>(id) );
	}
	else if (id.type == ItemDesc::SPELLBOOKDESC) // ITEMDESCTODO make new ItemDesc type
	{
		item = new Spellbook( static_cast<const SpellbookDesc&>(id) );
	}
	else if (id.type == ItemDesc::CONTAINERDESC)
	{
		item = new UContainer( static_cast<const ContainerDesc&>(id) );
	}
	else if (id.type == ItemDesc::WEAPONDESC)
	{
		// we call find_itemdesc here because the item descriptor passed in may not
		// be the "real" one - it may be a temporary descriptor.
		const WeaponDesc* permanent_descriptor = static_cast<const WeaponDesc*>(&find_itemdesc(objtype));
		item = new UWeapon( static_cast<const WeaponDesc&>(id), permanent_descriptor );
	}
	else if (id.type == ItemDesc::ARMORDESC)
	{
		const ArmorDesc* permanent_descriptor = static_cast<const ArmorDesc*>(&find_itemdesc(objtype));
		item = new UArmor( static_cast<const ArmorDesc&>(id), permanent_descriptor );
	}
	else if (id.type == ItemDesc::MAPDESC)  // (graphic >= UOBJ_MAP1 && graphic <= UOBJ_ROLLED_MAP2)
	{
		item = new Map( static_cast<const MapDesc&>(id) );
	}
	else if (objtype == EXTOBJ_PORT_PLANK || objtype == EXTOBJ_STARBOARD_PLANK)// ITEMDESCTODO make new ItemDesc type
	{
		item = new UPlank( id );
	}
	else if (objtype_is_lockable(objtype))
	{
		item = new ULockable( id, CLASS_ITEM );
	}
	else
	{
		item = new Item( id, CLASS_ITEM );
	}

	// 12-17-2008 MuadDib added for reading the tilelayer at all times while retaining item.layer useage.
	item->tile_layer = tilelayer( graphic );
	
	// Have to be set after the item is created, because item graphic changes
	// Because items can have facing 0 as the lightsource we use as default 127 to check
	if ( item->facing == 127 )
		item->facing = item->tile_layer;	

	if (serial)
	{
		item->serial = UseItemSerialNumber(serial);
		item->clear_dirty();
	}
	else if (dont_save_itemtype[objtype])
	{
		item->set_dirty();

		item->serial = GetNewItemSerialNumber();
	}
	else // creating something new
	{
		item->set_dirty();
		remove_resources( objtype, 1 );
		item->serial = GetNewItemSerialNumber();
	}
	
	////HASH
	objecthash.Insert(item);
	////

	item->serial_ext = ctBEu32( item->serial );

	item->restart_decay_timer();

	item->graphic = graphic;
	item->graphic_ext = ctBEu16( item->graphic );

	item->copyprops( id.props );

	#ifdef PERGON
	string value_self;
	if (!item->getprop( "ct", value_self )) // Pergon: Check if Prop still exist - prevents Overwrite on Server-Restart
	  item->setprop("ct", "i" + decint( read_gameclock() )); // Pergon: Init Property CreateTime for a new Item
	#endif

	if (!id.control_script.empty())
	{
		UOExecutorModule* uoemod = start_script( id.control_script, item->make_ref() );
		if (!uoemod)
		{
			Log( "Unable to start control script %s for %s\n",
					   id.control_script.name().c_str(),
					   id.objtype_description().c_str() );
		}
	}

	for( unsigned element = 0; element <= ELEMENTAL_TYPE_MAX; ++element )
	{
		switch(element)
		{
			case ELEMENTAL_FIRE: item->element_resist.fire = id.element_resist.fire;
								 item->element_damage.fire = id.element_damage.fire;break;
			case ELEMENTAL_COLD: item->element_resist.cold = id.element_resist.cold;
								 item->element_damage.cold = id.element_damage.cold;break;
			case ELEMENTAL_ENERGY: item->element_resist.energy = id.element_resist.energy;
								 item->element_damage.energy = id.element_damage.energy; break;
			case ELEMENTAL_POISON: item->element_resist.poison = id.element_resist.poison;
								   item->element_damage.poison = id.element_damage.poison; break;
			case ELEMENTAL_PHYSICAL: item->element_resist.physical = id.element_resist.physical;
									 item->element_damage.physical = id.element_damage.physical; break;
		}
	}

	// if ItemDesc is a dynamic one desc could differ and would be lost
	const ItemDesc& origid = find_itemdesc( item->objtype_ );
    if (id.desc != origid.desc)
		item->setname( id.desc);

	return item;
}