Beispiel #1
0
int32 do_sockets(fd_set* rfd, int32 next)
{
    struct timeval timeout;
    int32 ret;
    memcpy(rfd, &readfds, sizeof(*rfd));

    timeout.tv_sec = next / 1000;
    timeout.tv_usec = next % 1000 * 1000;

    ret = sSelect(fd_max, rfd, nullptr, nullptr, &timeout);

    if (ret == SOCKET_ERROR)
    {
        if (sErrno != S_EINTR)
        {
            ShowFatalError("do_sockets: select() failed, error code %d!\n", sErrno);
            do_final(EXIT_FAILURE);
        }
        return 0; // interrupted by a signal, just loop and try again
    }

    last_tick = time(nullptr);

    if (sFD_ISSET(map_fd, rfd))
    {
        struct sockaddr_in from;
        socklen_t fromlen = sizeof(from);

        int32 ret = recvudp(map_fd, g_PBuff, map_config.buffer_size, 0, (struct sockaddr*)&from, &fromlen);
        if (ret != -1)
        {
            // find player char
#   ifdef WIN32
            uint32 ip = ntohl(from.sin_addr.S_un.S_addr);
#   else
            uint32 ip = ntohl(from.sin_addr.s_addr);
#   endif

            uint64 port = ntohs(from.sin_port);
            uint64 ipp = ip;
            ipp |= port << 32;
            map_session_data_t* map_session_data = mapsession_getbyipp(ipp);

            if (map_session_data == nullptr)
            {
                map_session_data = mapsession_createsession(ip, ntohs(from.sin_port));
                if (map_session_data == nullptr)
                {
					map_session_list.erase(ipp);
                    return -1;
                }
            }

            map_session_data->last_update = time(nullptr);
            size_t size = ret;

            if (recv_parse(g_PBuff, &size, &from, map_session_data) != -1)
            {
                // если предыдущий пакет был потерян, то мы не собираем новый,
                // а отправляем предыдущий пакет повторно
                if (!parse(g_PBuff, &size, &from, map_session_data))
                {
                    send_parse(g_PBuff, &size, &from, map_session_data);
                }

                ret = sendudp(map_fd, g_PBuff, size, 0, (const struct sockaddr*)&from, fromlen);

                int8* data = g_PBuff;
                g_PBuff = map_session_data->server_packet_data;

                map_session_data->server_packet_data = data;
                map_session_data->server_packet_size = size;
            }
            if (map_session_data->shuttingDown > 0)
            {
                map_close_session(gettick(), map_session_data);
            }
        }
    }
    return 0;
}
Beispiel #2
0
int32 send_parse(int8 *buff, size_t* buffsize, sockaddr_in* from, map_session_data_t* map_session_data)
{
    // Модификация заголовка исходящего пакета
    // Суть преобразований:
    //  - отправить клиенту номер последнего полученного от него пакета
    //  - присвоить исходящему пакету номер последнего отправленного клиенту пакета +1
    //  - записать текущее время отправки пакета

    WBUFW(buff, 0) = map_session_data->server_packet_id;
    WBUFW(buff, 2) = map_session_data->client_packet_id;

    // сохранение текущего времени (32 BIT!)
    WBUFL(buff, 8) = (uint32)time(nullptr);

    // собираем большой пакет, состоящий из нескольких маленьких
    CCharEntity *PChar = map_session_data->PChar;
    CBasicPacket* PSmallPacket;
    uint32 PacketSize = UINT32_MAX;
    uint32 PacketCount = PChar->getPacketCount();
    uint8 packets = 0;

    while (PacketSize > 1300 - FFXI_HEADER_SIZE - 16) //max size for client to accept
    {
        *buffsize = FFXI_HEADER_SIZE;
        PacketList_t packetList = PChar->getPacketList();
        packets = 0;

        while (!packetList.empty() && *buffsize + packetList.front()->length() < map_config.buffer_size &&
            packets < PacketCount)
        {
            PSmallPacket = packetList.front();

            PSmallPacket->sequence(map_session_data->server_packet_id);
            memcpy(buff + *buffsize, *PSmallPacket, PSmallPacket->length());

            *buffsize += PSmallPacket->length();
            packetList.pop_front();
            packets++;
        }
        //Сжимаем данные без учета заголовка
        //Возвращаемый размер в 8 раз больше реальных данных
        PacketSize = zlib_compress(buff + FFXI_HEADER_SIZE, *buffsize - FFXI_HEADER_SIZE, PTempBuff, *buffsize, zlib_compress_table);
        WBUFL(PTempBuff, (PacketSize + 7) / 8) = PacketSize;

        PacketSize = (PacketSize + 7) / 8 + 4;

        PacketCount /= 2;
    }
    PChar->erasePackets(packets);

    //Запись размера данных без учета заголовка
    uint8 hash[16];
    md5((uint8*)PTempBuff, hash, PacketSize);
    memcpy(PTempBuff + PacketSize, hash, 16);
    PacketSize += 16;

    if (PacketSize > map_config.buffer_size + 20)
    {
        ShowFatalError(CL_RED"%Memory manager: PTempBuff is overflowed (%u)\n" CL_RESET, PacketSize);
    }

    //making total packet
    memcpy(buff + FFXI_HEADER_SIZE, PTempBuff, PacketSize);

    uint32 CypherSize = (PacketSize / 4)&-2;

    blowfish_t* pbfkey = &map_session_data->blowfish;

    for (uint32 j = 0; j < CypherSize; j += 2)
    {
        blowfish_encipher((uint32*)(buff)+j + 7, (uint32*)(buff)+j + 8, pbfkey->P, pbfkey->S[0]);
    }

    // контролируем размер отправляемого пакета. в случае,
    // если его размер превышает 1400 байт (размер данных + 42 байта IP заголовок),
    // то клиент игнорирует пакет и возвращает сообщение о его потере

    // в случае возникновения подобной ситуации выводим предупреждующее сообщение и
    // уменьшаем размер BuffMaxSize с шагом в 4 байта до ее устранения (вручную)

    *buffsize = PacketSize + FFXI_HEADER_SIZE;

    return 0;
}
Beispiel #3
0
//---------------------------------------------------------
// 倉庫データを読み込む
int inter_storage_init()
{
	char line[65536];
	int c = 0;
	FILE *fp;

	storage_db = idb_alloc(DB_OPT_RELEASE_DATA);

	fp=fopen(storage_txt,"r");
	if(fp==NULL){
		ShowError("can't read : %s\n",storage_txt);
		return 1;
	}
	while( fgets(line, sizeof(line), fp) )
	{
		int account_id;
		struct storage_data *s;

		s = (struct storage_data*)aCalloc(sizeof(struct storage_data), 1);
		if( s == NULL )
		{
			ShowFatalError("int_storage: out of memory!\n");
			exit(EXIT_FAILURE);
		}

		if( storage_fromstr(line,&account_id,s) )
		{
			idb_put(storage_db,account_id,s);
		}
		else{
			ShowError("int_storage: broken data in [%s] line %d\n",storage_txt,c);
			aFree(s);
		}
		c++;
	}
	fclose(fp);

	c = 0;
	guild_storage_db = idb_alloc(DB_OPT_RELEASE_DATA);

	fp=fopen(guild_storage_txt,"r");
	if(fp==NULL){
		ShowError("can't read : %s\n",guild_storage_txt);
		return 1;
	}
	while(fgets(line, sizeof(line), fp))
	{
		int tmp_int;
		struct guild_storage *gs;

		sscanf(line,"%d",&tmp_int);
		gs = (struct guild_storage*)aCalloc(sizeof(struct guild_storage), 1);
		if(gs==NULL){
			ShowFatalError("int_storage: out of memory!\n");
			exit(EXIT_FAILURE);
		}
//		memset(gs,0,sizeof(struct guild_storage)); aCalloc...
		gs->guild_id=tmp_int;
		if(gs->guild_id > 0 && guild_storage_fromstr(line,gs) == 0) {
			idb_put(guild_storage_db,gs->guild_id,gs);
		}
		else{
			ShowError("int_storage: broken data [%s] line %d\n",guild_storage_txt,c);
			aFree(gs);
		}
		c++;
	}
	fclose(fp);

	return 0;
}
Beispiel #4
0
mempool mempool_create(const char *name,
						uint64 elem_size,
						uint64 initial_count,
						uint64 realloc_count,
						memPoolOnNodeAllocationProc onNodeAlloc,
						memPoolOnNodeDeallocationProc onNodeDealloc){
	//..
	uint64 realloc_thresh;
	mempool pool;
	pool = (mempool)aCalloc( 1,  sizeof(struct mempool) );
	
	if(pool == NULL){
		ShowFatalError("mempool_create: Failed to allocate %u bytes memory.\n", sizeof(struct mempool) );
		exit(EXIT_FAILURE);		
	}
	
	// Check minimum initial count / realloc count requirements.
	if(initial_count < 50)
		initial_count = 50;
	if(realloc_count < 50)
		realloc_count = 50;
	
	// Set Reallocation threshold to 5% of realloc_count, at least 10.
	realloc_thresh = (realloc_count/100)*5; // 
	if(realloc_thresh < 10)
		realloc_thresh = 10;

	// Initialize members..
	pool->name = aStrdup(name);
	pool->elem_size	= ALIGN_TO_16(elem_size);
	pool->elem_realloc_step = realloc_count;
	pool->elem_realloc_thresh = realloc_thresh;
	pool->onalloc = onNodeAlloc;
	pool->ondealloc = onNodeDealloc;
	
	InitializeSpinLock(&pool->segmentLock);
	InitializeSpinLock(&pool->nodeLock);

	// Initial Statistic values:
	pool->num_nodes_total = 0;
	pool->num_nodes_free = 0;
	pool->num_segments = 0;
	pool->num_bytes_total = 0;
	pool->peak_nodes_used = 0;
	pool->num_realloc_events = 0;
		
	//
#ifdef MEMPOOL_DEBUG
	ShowDebug("Mempool [%s] Init (ElemSize: %u,  Initial Count: %u,  Realloc Count: %u)\n", pool->name,  pool->elem_size,  initial_count,  pool->elem_realloc_step);
#endif

	// Allocate first segment directly :) 	
	segment_allocate_add(pool, initial_count);
	

	// Add Pool to the global pool list
	EnterSpinLock(&l_mempoolListLock);
		pool->next = l_mempoolList;
		l_mempoolList = pool;
	LeaveSpinLock(&l_mempoolListLock);

	
	return pool;	
}//end: mempool_create()
Beispiel #5
0
static struct conf_value *makeValue(const char *key, char *val, size_t val_len){
	struct conf_value *v;
/*	size_t sz;
		
	sz = sizeof(struct conf_value);
	if(val_len >=  sizeof(v->strval))
		sz += (val_len - sizeof(v->strval) +  1);*/
	
	v = (struct conf_value*)aCalloc(1, sizeof(struct conf_value));
	if(v == NULL){
		ShowFatalError("raconf: makeValue => Out of Memory while allocating new node.\n");
		return NULL;
	}
	
	memcpy(v->strval, val, val_len);
	v->strval[val_len+1] = '\0';
	v->strval_len = val_len;
	
	
	// Parse boolean value:
	if((val_len == 4)  &&  (strncmpi("true", val, 4) == 0))
		v->bval = true;
	else if((val_len == 3) && (strncmpi("yes", val, 3) == 0))
		v->bval = true;
	else if((val_len == 3) && (strncmpi("oui", val, 3) == 0))
		v->bval = true;
	else if((val_len == 2) && (strncmpi("si", val, 2) == 0))
		v->bval = true;
	else if((val_len == 2) && (strncmpi("ja", val, 2) == 0))
		v->bval = true;
	else if((val_len == 1) && (*val == '1'))
		v->bval = true;
	else if((val_len == 5) && (strncmpi("false", val, 5) == 0))
		v->bval = false;
	else if((val_len == 2) && (strncmpi("no", val, 2) == 0))
		v->bval = false;
	else if((val_len == 3) && (strncmpi("non", val, 3) == 0))
		v->bval = false;
	else if((val_len == 2) && (strncmpi("no", val, 2) == 0))
		v->bval = false;
	else if((val_len == 4) && (strncmpi("nein", val, 4) == 0))
		v->bval = false;
	else if((val_len == 1) && (*val == '0'))
		v->bval = false;		
	else
		v->bval = false; // assume false.
		
	// Parse number
	// Supported formats:
	// prefix: 0x hex . 
	// postix: h for hex
	//		   b for bin (dual)
	if( (val_len >= 1 && (val[val_len] == 'h')) || (val_len >= 2 && (val[0] == '0' && val[1] == 'x')) ){//HEX!
			if(val[val_len] == 'h'){
				val[val_len]= '\0';
				v->intval = strtoull(val, NULL, 16);
				val[val_len] = 'h';
			}else
				v->intval = strtoull(&val[2], NULL, 16);
	}else if( val_len >= 1 && (val[val_len] == 'b') ){	//BIN
		val[val_len] = '\0';
		v->intval = strtoull(val, NULL, 2);
		val[val_len] = 'b';
	}else if( *val >='0' && *val <= '9'){	// begins with normal digit, so assume its dec.
		// is it float?
		bool is_float = false;
		char *p;
		
		for(p = val; *p != '\0'; p++){
			if(*p == '.'){
				v->floatval = strtod(val, NULL);
				v->intval = (int64) v->floatval;
				is_float = true;
				break;
			}
		}
		
		if(is_float == false){
			v->intval = strtoull(val, NULL, 10);
			v->floatval = (double) v->intval;
		}
	}else{
		// Everything else: lets use boolean for fallback
		if(v->bval == true)
			v->intval = 1;
		else
			v->intval = 0;
	}
	
	return v;	
}//end: makeValue()
Beispiel #6
0
// initialize
int inter_init(const char *file)
{
    //int i;

    ShowInfo ("interserver initialize...\n");
    inter_config_read(file);

    //DB connection initialized
    mysql_init(&mysql_handle);
    ShowInfo("Connect Character DB server.... (Character Server)\n");
    if(!mysql_real_connect(&mysql_handle, char_server_ip, char_server_id, char_server_pw,
                           char_server_db ,char_server_port, (char *)NULL, 0)) {
        //pointer check
        ShowFatalError("%s\n",mysql_error(&mysql_handle));
        exit(1);
    }
    else if (inter_sql_test()) {
        ShowStatus("Connect Success! (Character Server)\n");
    }

    if(char_gm_read) {
        mysql_init(&lmysql_handle);
        ShowInfo("Connect Character DB server.... (login server)\n");
        if(!mysql_real_connect(&lmysql_handle, login_server_ip, login_server_id, login_server_pw,
                               login_server_db ,login_server_port, (char *)NULL, 0)) {
            //pointer check
            ShowFatalError("%s\n",mysql_error(&lmysql_handle));
            exit(1);
        } else {
            ShowStatus ("Connect Success! (Login Server)\n");
        }
    }
    if(strlen(default_codepage) > 0 ) {
        sprintf( tmp_sql, "SET NAMES %s", default_codepage );
        if (mysql_query(&mysql_handle, tmp_sql)) {
            ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
            ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
        }
        if(char_gm_read)
            if (mysql_query(&lmysql_handle, tmp_sql)) {
                ShowSQL("DB error - %s\n",mysql_error(&lmysql_handle));
                ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
            }
    }
    wis_db = db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_RELEASE_DATA,sizeof(int));
    inter_guild_sql_init();
    inter_storage_sql_init();
    inter_party_sql_init();

    inter_pet_sql_init();
    inter_accreg_sql_init();

    //printf ("interserver timer initializing : %d sec...\n",autosave_interval);
    //i=add_timer_interval(gettick()+autosave_interval,inter_save_timer,0,0,autosave_interval);

    if (connection_ping_interval) {
        add_timer_func_list(inter_sql_ping, "inter_sql_ping");
        add_timer_interval(gettick()+connection_ping_interval*60*60*1000,
                           inter_sql_ping, 0, 0, connection_ping_interval*60*60*1000);
    }
    return 0;
}
Beispiel #7
0
QM_Model QM_ReadFile( const char *filename )
	// Read model from input file.
	// The output QM_Model has only QM_OrigQuad.
	// The axis-aligned bounding box is computed.
{
	char badFile[] = "Invalid input model file";
	char badEOF[] = "Unexpected end of file";
	char lineBuf[ MAX_LINE_LEN + 1 ];

	// Open input file
	FILE *fp = fopen( filename, "r" );
	if ( fp == NULL ) 
		ShowFatalError( __FILE__, __LINE__, "Cannot open input model file \"%s\"", filename );

	int lineNum = 0;

//=== VERTICES ===

	int numVertices = 0;
	float *vertexTable = NULL;  // An array of 3D vertices.

	// Read number of vertices.
	if ( !ReadDataLine( lineBuf, &lineNum, filename, fp ) )
		ShowFatalError( __FILE__, __LINE__, "%s \"%s\"", badEOF, filename );

	if ( sscanf( lineBuf, "%d", &numVertices ) != 1  ||  numVertices < 0 )
		ShowFatalError( __FILE__, __LINE__, "%s \"%s\" at line %d", badFile, filename, lineNum );

	vertexTable = (float *) CheckedMalloc( sizeof(float) * 3 * numVertices );

	// Read the vertices.
	for ( int v = 0; v < numVertices; v++ )
	{
		float x, y, z;

		if ( !ReadDataLine( lineBuf, &lineNum, filename, fp ) )
			ShowFatalError( __FILE__, __LINE__, "%s \"%s\"", badEOF, filename );

		if ( sscanf( lineBuf, "%f %f %f", &x, &y, &z ) != 3 )
			ShowFatalError( __FILE__, __LINE__, "%s \"%s\" at line %d", badFile, filename, lineNum );

		vertexTable[ 3 * v + 0 ] = x;
		vertexTable[ 3 * v + 1 ] = y;
		vertexTable[ 3 * v + 2 ] = z;
	}


//=== MATERIALS ===

	int numMaterials = 0;
	float *reflectivityTable = NULL;	// An array of RGB reflectivity values.
	float *emissionTable = NULL;		// An array of RGB emission values.

	// Read number of materials.
	if ( !ReadDataLine( lineBuf, &lineNum, filename, fp ) )
		ShowFatalError( __FILE__, __LINE__, "%s \"%s\"", badEOF, filename );

	if ( sscanf( lineBuf, "%d", &numMaterials ) != 1  ||  numMaterials < 0 )
		ShowFatalError( __FILE__, __LINE__, "%s \"%s\" at line %d", badFile, filename, lineNum );

	reflectivityTable = (float *) CheckedMalloc( sizeof(float) * 3 * numMaterials );
	emissionTable = (float *) CheckedMalloc( sizeof(float) * 3 * numMaterials );

	// Read the materials.
	for ( int m = 0; m < numMaterials; m++ )
	{
		float r, g, b;

		if ( !ReadDataLine( lineBuf, &lineNum, filename, fp ) )
			ShowFatalError( __FILE__, __LINE__, "%s \"%s\"", badEOF, filename );

		if ( sscanf( lineBuf, "%f %f %f", &r, &g, &b ) != 3 )
			ShowFatalError( __FILE__, __LINE__, "%s \"%s\" at line %d", badFile, filename, lineNum );

		reflectivityTable[ 3 * m + 0 ] = r;
		reflectivityTable[ 3 * m + 1 ] = g;
		reflectivityTable[ 3 * m + 2 ] = b;

		if ( !ReadDataLine( lineBuf, &lineNum, filename, fp ) )
			ShowFatalError( __FILE__, __LINE__, "%s \"%s\"", badEOF, filename );

		if ( sscanf( lineBuf, "%f %f %f", &r, &g, &b ) != 3 )
			ShowFatalError( __FILE__, __LINE__, "%s \"%s\" at line %d", badFile, filename, lineNum );

		emissionTable[ 3 * m + 0 ] = r;
		emissionTable[ 3 * m + 1 ] = g;
		emissionTable[ 3 * m + 2 ] = b;
	}


//=== SURFACES ===

	int numSurfaces = 0;
	QM_Surface *surfaceTable = NULL;	// An array of surfaces.

	// Read number of surfaces.
	if ( !ReadDataLine( lineBuf, &lineNum, filename, fp ) )
		ShowFatalError( __FILE__, __LINE__, "%s \"%s\"", badEOF, filename );

	if ( sscanf( lineBuf, "%d", &numSurfaces ) != 1  ||  numSurfaces < 0 )
		ShowFatalError( __FILE__, __LINE__, "%s \"%s\" at line %d", badFile, filename, lineNum );

	surfaceTable = (QM_Surface *) CheckedMalloc( sizeof(QM_Surface) * numSurfaces );

	// Read the surfaces.
	for ( int s = 0; s < numSurfaces; s++ )
	{
		QM_SurfaceInit( &surfaceTable[s] );

		int matID, numQuads;

		// Read material index.
		if ( !ReadDataLine( lineBuf, &lineNum, filename, fp ) )
			ShowFatalError( __FILE__, __LINE__, "%s \"%s\"", badEOF, filename );

		if ( sscanf( lineBuf, "%d", &matID ) != 1  ||  matID < 0 || matID >= numMaterials )
			ShowFatalError( __FILE__, __LINE__, "%s \"%s\" at line %d", badFile, filename, lineNum );

		CopyArray3( surfaceTable[s].reflectivity, &reflectivityTable[3*matID] );
		CopyArray3( surfaceTable[s].emission, &emissionTable[3*matID] );

		// Read number of quadrilaterals in the surface.
		if ( !ReadDataLine( lineBuf, &lineNum, filename, fp ) )
			ShowFatalError( __FILE__, __LINE__, "%s \"%s\"", badEOF, filename );

		if ( sscanf( lineBuf, "%d", &numQuads ) != 1  ||  numQuads < 0 )
			ShowFatalError( __FILE__, __LINE__, "%s \"%s\" at line %d", badFile, filename, lineNum );

		surfaceTable[s].numOrigQuads = numQuads;
		surfaceTable[s].origQuads = (QM_OrigQuad *) CheckedMalloc( sizeof(QM_OrigQuad) * numQuads );

		// Read vertex indices for each quadrilateral.
		for ( int q = 0; q < numQuads; q++ )
		{
			int vertID[4];

			if ( !ReadDataLine( lineBuf, &lineNum, filename, fp ) )
				ShowFatalError( __FILE__, __LINE__, "%s \"%s\"", badEOF, filename );

			if ( sscanf( lineBuf, "%d %d %d %d", &vertID[0], &vertID[1], &vertID[2], &vertID[3] ) != 4 || 
				 vertID[0] < 0 || vertID[0] >= numVertices || vertID[1] < 0 || vertID[1] >= numVertices ||
				 vertID[2] < 0 || vertID[2] >= numVertices || vertID[3] < 0 || vertID[3] >= numVertices )
				ShowFatalError( __FILE__, __LINE__, "%s \"%s\" at line %d", badFile, filename, lineNum );

			CopyArray3( surfaceTable[s].origQuads[q].v[0], &vertexTable[ 3*vertID[0] ] );
			CopyArray3( surfaceTable[s].origQuads[q].v[1], &vertexTable[ 3*vertID[1] ] );
			CopyArray3( surfaceTable[s].origQuads[q].v[2], &vertexTable[ 3*vertID[2] ] );
			CopyArray3( surfaceTable[s].origQuads[q].v[3], &vertexTable[ 3*vertID[3] ] );

			// Compute normal vector to the quadrilateral.
			VecTriNormal( surfaceTable[s].origQuads[q].normal, 
				          surfaceTable[s].origQuads[q].v[0], 
						  surfaceTable[s].origQuads[q].v[1], 
						  surfaceTable[s].origQuads[q].v[2] );
			VecNormalize( surfaceTable[s].origQuads[q].normal, surfaceTable[s].origQuads[q].normal );
		}
	}

	QM_Model model = QM_ModelInit();
	model.numSurfaces = numSurfaces;
	model.surfaces = surfaceTable;
	ComputeBoundingBox( &model );

	fclose( fp );
	free( vertexTable );
	free( reflectivityTable );
	free( emissionTable );
	return model;
}
Beispiel #8
0
void CZone::LoadZoneSettings()
{
    static const int8* Query =
        "SELECT "
          "zone.name,"
          "zone.zoneip,"
          "zone.zoneport,"
          "zone.music_day,"
          "zone.music_night,"
          "zone.battlesolo,"
          "zone.battlemulti,"
          "zone.tax,"
          "zone.misc,"
          "zone.navmesh,"
          "zone.zonetype,"
          "bcnm.name,"
		  "zone.eventtype "
        "FROM zone_settings AS zone "
        "LEFT JOIN bcnm_info AS bcnm "
        "USING (zoneid) "
        "WHERE zoneid = %u "
        "LIMIT 1";

    if (Sql_Query(SqlHandle, Query, m_zoneID) != SQL_ERROR &&
        Sql_NumRows(SqlHandle) != 0 &&
        Sql_NextRow(SqlHandle) == SQL_SUCCESS)
    {
        m_zoneName.insert(0, Sql_GetData(SqlHandle,0));

        m_zoneIP   = inet_addr(Sql_GetData(SqlHandle,1));
        m_zonePort = (uint16)Sql_GetUIntData(SqlHandle,2);
        m_zoneMusic.m_songDay = (uint8)Sql_GetUIntData(SqlHandle, 3);   // background music (day)
		m_zoneMusic.m_songNight = (uint8)Sql_GetUIntData(SqlHandle, 4);   // background music (night)
        m_zoneMusic.m_bSongS = (uint8)Sql_GetUIntData(SqlHandle,5);   // solo battle music
        m_zoneMusic.m_bSongM = (uint8)Sql_GetUIntData(SqlHandle,6);   // party battle music
        m_tax = (uint16)(Sql_GetFloatData(SqlHandle,7) * 100);      // tax for bazaar
        m_miscMask = (uint16)Sql_GetUIntData(SqlHandle,8);
        m_useNavMesh = (bool)Sql_GetIntData(SqlHandle,9);
		m_eventType = (EVENTTYPE)Sql_GetUIntData(SqlHandle, 12);
		if (luautils::IsSummerfestYearRound())
		{
			if ((EVENTTYPE)Sql_GetUIntData(SqlHandle, 12) >= 3)
			{
				m_zoneMusic.m_songNight = 227;   // background music (night)
			}
		}
		m_zoneType = (ZONETYPE)Sql_GetUIntData(SqlHandle, 10);
		
		//luautils::OnZoneWeatherChange(GetID(), Weather);
        if (Sql_GetData(SqlHandle,11) != nullptr) // сейчас нельзя использовать bcnmid, т.к. они начинаются с нуля
        {
            m_BattlefieldHandler = new CBattlefieldHandler(m_zoneID);
        }
        if (m_miscMask & MISC_TREASURE)
        {
            m_TreasurePool = new CTreasurePool(TREASUREPOOL_ZONE);
        }
    }
    else
    {
        ShowFatalError(CL_RED"CZone::LoadZoneSettings: Cannot load zone settings (%u)\n" CL_RESET, m_zoneID);
    }
}
Beispiel #9
0
void* _mmalloc(size_t size, const char *file, int line, const char *func )
{
	struct block *block;
	short size_hash = size2hash( size );
	struct unit_head *head;

	if (((long) size) < 0) {
		ShowError("_mmalloc: %d\n", size);
		return NULL;
	}
	
	if(size == 0) {
		return NULL;
	}
	memmgr_usage_bytes += size;

	/* To ensure the area that exceeds the length of the block, using malloc () to */
	/* At that time, the distinction by assigning NULL to unit_head.block */
	if(hash2size(size_hash) > BLOCK_DATA_SIZE - sizeof(struct unit_head)) {
		struct unit_head_large* p = (struct unit_head_large*)MALLOC(sizeof(struct unit_head_large)+size,file,line,func);
		if(p != NULL) {
			p->size            = size;
			p->unit_head.block = NULL;
			p->unit_head.size  = 0;
			p->unit_head.file  = file;
			p->unit_head.line  = line;
			p->prev = NULL;
			if (unit_head_large_first == NULL)
				p->next = NULL;
			else {
				unit_head_large_first->prev = p;
				p->next = unit_head_large_first;
			}
			unit_head_large_first = p;
			*(long*)((char*)p + sizeof(struct unit_head_large) - sizeof(long) + size) = 0xdeadbeaf;
			return (char *)p + sizeof(struct unit_head_large) - sizeof(long);
		} else {
			ShowFatalError("Memory manager::memmgr_alloc failed (allocating %d+%d bytes at %s:%d).\n", sizeof(struct unit_head_large), size, file, line);
			exit(EXIT_FAILURE);
		}
	}

	/* When a block of the same size is not ensured, to ensure a new */
	if(hash_unfill[size_hash]) {
		block = hash_unfill[size_hash];
	} else {
		block = block_malloc(size_hash);
	}

	if( block->unit_unfill == 0xFFFF ) {
		// there are no more free space that
		memmgr_assert(block->unit_used <  block->unit_count);
		memmgr_assert(block->unit_used == block->unit_maxused);
		head = block2unit(block, block->unit_maxused);
		block->unit_used++;
		block->unit_maxused++;
	} else {
		head = block2unit(block, block->unit_unfill);
		block->unit_unfill = head->size;
		block->unit_used++;
	}

	if( block->unit_unfill == 0xFFFF && block->unit_maxused >= block->unit_count) {
		// Since I ran out of the unit, removed from the list unfill
		if( block->unfill_prev == &block_head) {
			hash_unfill[ size_hash ] = block->unfill_next;
		} else {
			block->unfill_prev->unfill_next = block->unfill_next;
		}
		if( block->unfill_next ) {
			block->unfill_next->unfill_prev = block->unfill_prev;
		}
		block->unfill_prev = NULL;
	}

#ifdef DEBUG_MEMMGR
	{
		size_t i, sz = hash2size( size_hash );
		for( i=0; i<sz; i++ )
		{
			if( ((unsigned char*)head)[ sizeof(struct unit_head) - sizeof(long) + i] != 0xfd )
			{
				if( head->line != 0xfdfd )
				{
					ShowError("Memory manager: freed-data is changed. (freed in %s line %d)\n", head->file,head->line);
				}
				else
				{
					ShowError("Memory manager: not-allocated-data is changed.\n");
				}
				break;
			}
		}
		memset( (char *)head + sizeof(struct unit_head) - sizeof(long), 0xcd, sz );
	}
#endif

	head->block = block;
	head->file  = file;
	head->line  = line;
	head->size  = (unsigned short)size;
	*(long*)((char*)head + sizeof(struct unit_head) - sizeof(long) + size) = 0xdeadbeaf;
	return (char *)head + sizeof(struct unit_head) - sizeof(long);
}
Beispiel #10
0
/*==========================================
 * アイテムデータベースの読み込み
 *------------------------------------------
 */
static int itemdb_readdb(void)
{
	FILE *fp;
	char line[1024];
	int ln=0,lines=0;
	int nameid,j;
	char *str[32],*p,*np;
	struct item_data *id;
	int i=0;
	char *filename[]={ "item_db.txt","item_db2.txt" };

	for(i=0;i<2;i++){
		sprintf(line, "%s/%s", db_path, filename[i]);
		fp=fopen(line,"r");
		if(fp==NULL){
			if(i>0)
				continue;
			ShowFatalError("can't read %s\n",line);
			exit(1);
		}

		lines=0;
		while(fgets(line,1020,fp)){
			lines++;
			if(line[0]=='/' && line[1]=='/')
				continue;
			memset(str,0,sizeof(str));
			for(j=0,np=p=line;j<19 && p;j++){
				str[j]=p;
				p=strchr(p,',');
				if(p){ *p++=0; np=p; }
			}
			if(str[0]==NULL)
				continue;

			nameid=atoi(str[0]);
			if(nameid<=0 || nameid>=20000)
				continue;
			if (j < 19)
			{	//Crash-fix on broken item lines. [Skotlex]
				ShowWarning("Reading %s: Insufficient fields for item with id %d, skipping.\n", filename[i], nameid);
				continue;
			}
			ln++;

			//ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View
			id=itemdb_search(nameid);
			memcpy(id->name, str[1], ITEM_NAME_LENGTH-1);
			memcpy(id->jname, str[2], ITEM_NAME_LENGTH-1);
			id->type=atoi(str[3]);
			if (id->type == 11)
			{	//Items that are consumed upon target confirmation
				//(yggdrasil leaf, spells & pet lures) [Skotlex]
				id->type = 2;
				id->flag.delay_consume=1;
			}

			{
				int buy = atoi(str[4]), sell = atoi(str[5]);
				// if buying price > selling price * 2 consider it valid and don't change it [celest]
				if (buy && sell && buy > sell*2){
					id->value_buy = buy;
					id->value_sell = sell;
				} else {
					// buy≠sell*2 は item_value_db.txt で指定してください。
					if (sell) {		// sell値を優先とする
						id->value_buy = sell*2;
						id->value_sell = sell;
					} else {
						id->value_buy = buy;
						id->value_sell = buy/2;
					}
				}
				// check for bad prices that can possibly cause exploits
				if (id->value_buy*75/100 < id->value_sell*124/100) {
					ShowWarning ("Item %s [%d] buying:%d < selling:%d\n",
						id->name, id->nameid, id->value_buy*75/100, id->value_sell*124/100);
				}
			}
			id->weight=atoi(str[6]);
			id->atk=atoi(str[7]);
			id->def=atoi(str[8]);
			id->range=atoi(str[9]);
			id->slot=atoi(str[10]);
			if (id->slot > MAX_SLOTS)
			{
				ShowWarning("itemdb_readdb: Item %d (%s) specifies %d slots, but the server only supports up to %d\n", nameid, id->jname, id->slot, MAX_SLOTS);
				id->slot = MAX_SLOTS;
			}
			itemdb_jobid2mapid(id->class_base, atoi(str[11]));
			id->class_upper = atoi(str[12]);
			id->sex	= atoi(str[13]);
			if(id->equip != atoi(str[14])){
				id->equip=atoi(str[14]);
			}
			id->wlv=atoi(str[15]);
			id->elv=atoi(str[16]);
			id->flag.no_refine = atoi(str[17])?0:1;	//If the refine column is 1, no_refine is 0
			id->look=atoi(str[18]);
			id->flag.available=1;
			id->flag.value_notdc=0;
			id->flag.value_notoc=0;
			id->view_id=0;
			id->sex = itemdb_gendercheck(id); //Apply gender filtering.

			if (id->script) {
				aFree(id->script);
				id->script=NULL;
			}
			if((p=strchr(np,'{'))==NULL)
				continue;
			id->script = parse_script((unsigned char *) p,lines);
		}
		fclose(fp);
		if (ln > 0) {
			ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,filename[i]);
		}
		ln=0;	// reset to 0
	}
	return 0;
}
Beispiel #11
0
void netbuffer_init()
{
    char localsection[32];
    raconf conf;
    sysint i;

    // Initialize Statistic counters:
    l_nEmergencyAllocations = 0;

    // Set localsection name according to running serverype.
    switch(SERVER_TYPE) {
    case ATHENA_SERVER_LOGIN:
        strcpy(localsection, "login-netbuffer");
        break;
    case ATHENA_SERVER_CHAR:
        strcpy(localsection, "char-netbuffer");
        break;
    case ATHENA_SERVER_INTER:
        strcpy(localsection, "inter-netbuffer");
        break;
    case ATHENA_SERVER_MAP:
        strcpy(localsection, "map-netbuffer");
        break;
    default:
        strcpy(localsection, "unsupported_type");
        break;
    }


    conf = raconf_parse("conf/network.conf");
    if(conf == NULL) {
        ShowFatalError(read_message("Source.common.net_buffer_init"));
        exit(EXIT_FAILURE);
    }

    // Get Values from config file
    l_nPools = (sysint)raconf_getintEx(conf,  localsection,  "netbuffer", "num", 0);
    if(l_nPools == 0) {
        ShowFatalError(read_message("Source.common.net_buffer_init2"));
        exit(EXIT_FAILURE);
    }

    // Allocate arrays.
    l_poolElemSize = (sysint *)aCalloc(l_nPools, sizeof(sysint));
    l_pool = (mempool *)aCalloc(l_nPools, sizeof(mempool));


    for(i = 0; i < l_nPools; i++) {
        int64 num_prealloc, num_realloc;
        char key[32];

        sprintf(key, "pool_%u_size", (uint32)i+1);
        l_poolElemSize[i] = (sysint)raconf_getintEx(conf, localsection, "netbuffer", key, 4096);
        if(l_poolElemSize[i] < 32) {
            ShowWarning(read_message("Source.common.net_buffer_init3"));
            l_poolElemSize[i] = 32;
        }

        sprintf(key, "pool_%u_prealloc", (uint32)i+1);
        num_prealloc = raconf_getintEx(conf, localsection, "netbuffer", key, 150);

        sprintf(key, "pool_%u_realloc_step", (uint32)i+1);
        num_realloc = raconf_getintEx(conf, localsection, "netbuffer", key, 100);

        // Create Pool!
        sprintf(key, "Netbuffer %u", (uint32)l_poolElemSize[i]); // name.

        // Info
        ShowInfo(read_message("Source.net_buffer_init4"), l_poolElemSize[i], num_prealloc, num_realloc, (float)((sizeof(struct netbuf) + l_poolElemSize[i] - 32)* num_prealloc)/1024.0f/1024.0f);

        //
        // Size Calculation:
        //  struct netbuf  +  requested buffer size - 32 (because the struct already contains 32 byte buffer space at the end of struct)
        l_pool[i] = mempool_create(key, (sizeof(struct netbuf) + l_poolElemSize[i] - 32),  num_prealloc,  num_realloc, NULL, NULL);
        if(l_pool[i] == NULL) {
            ShowFatalError(read_message("Source.net_buffer_init5"), l_poolElemSize[i]);
            // @leak: clean everything :D
            exit(EXIT_FAILURE);
        }

    }//


    raconf_destroy(conf);

}//end: netbuffer_init()
Beispiel #12
0
/* ブロックを確保する */
static struct block* block_malloc(void) {
	if(block_unused != NULL) {
		/* ブロック用の領域は確保済み */
		struct block* ret = block_unused;
		do {
			block_unused = block_unused->block_next;
		} while(block_unused != NULL && block_unused->unit_size != 0);
		return ret;
	} else {
		/* ブロック用の領域を新たに確保する */
		int i;
		int block_no;
		struct block* p;
		struct chunk* chunk;
		char *pb = (char *) CALLOC (sizeof(struct block),BLOCK_ALLOC + 1);
		if(pb == NULL) {
			ShowFatalError("Administrador de memoria::block_alloc falhou.\n");
			exit(1);
		}

		// store original block address in chunk
		chunk = (struct chunk *) MALLOC (sizeof(struct chunk));
		if (chunk == NULL) {
			ShowFatalError("Administrador de Memoria::block_alloc falhou.\n");
			exit(1);
		}
		chunk->block = pb;
		chunk->next = (chunk_first) ? chunk_first : NULL;
		chunk_first = chunk;

		// ブロックのポインタの先頭をsizeof(block) アライメントに揃える
		// このアドレスをfree() することはないので、直接ポインタを変更している。
		pb += sizeof(struct block) - ((unsigned long)pb % sizeof(struct block));
		p   = (struct block*)pb;
		if(block_first == NULL) {
			/* 初回確保 */
			block_no     = 0;
			block_first  = p;
		} else {
			block_no      = block_last->block_no + 1;
			block_last->block_next = p;
			p->block_prev = block_last;
		}
		block_last = &p[BLOCK_ALLOC - 1];
		/* ブロックを連結させる */
		for(i=0;i<BLOCK_ALLOC;i++) {
			if(i != 0) {
				p[i].block_prev = &p[i-1];
			}
			if(i != BLOCK_ALLOC -1) {
				p[i].block_next = &p[i+1];
			}
			p[i].block_no = block_no + i;
		}

		/* 未使用ブロックへのポインタを更新 */
		block_unused = &p[1];
		p->unit_size = 1;
		return p;
	}
}
/*==============================================================*
* Function:	Auth::Run											*                                                     
* Author: GreenBox                                              *
* Date: 08/12/11 												*
* Description: Start Auth-Server and load configurations        *
**==============================================================*/
void AuthServer::run()
{
	boost::asio::io_service io_service;

	// Read Config Files
	try
	{
		auth_config = new config_file("./Config/authserver.conf");
		{
			config.network_bindip = auth_config->read<string>("network.bindip", "0.0.0.0");
			config.network_bindport = auth_config->read<unsigned short>("network.bindport", 6900);
			config.auth_use_md5 = auth_config->read<bool>("auth.use_md5", false);
		}
		ShowStatus("Finished reading authserver.conf.\n");
	}
	catch (config_file::file_not_found *fnf)
	{
		ShowFatalError("Config file not found: %s.\n", fnf->filename);
		return;
	}

	TimerManager::Initialize(&io_service);

	// Initialize Database System
	{
		ShowInfo("Opening connection to database...\n");

		try
		{
			database = database_helper::get_session(auth_config);
		}
		catch (soci::soci_error err)
		{
			ShowFatalError("Error opening database connection: %s\n", err.what());
			return;
		}

		accounts = new AccountDB(database);

		ShowSQL("Successfully opened database connection.\n");
	}

	// Initialize Network System
	{
		boost::system::error_code err;
		address_v4 bindip = address_v4::from_string(config.network_bindip, err);

		if (err)
		{
			ShowFatalError("%s\n", err.message().c_str());
			return;
		}

		server = new tcp_server(io_service, (address)bindip, config.network_bindport);
		server->set_default_parser(AuthServer::parse_from_client);

		ShowStatus("AuthServer is ready and listening on %s:%d.\n", config.network_bindip.c_str(), config.network_bindport);
	}

	// Run IO service service and start pooling events
	io_service.run();
}
Beispiel #14
0
int do_sockets(fd_set* rfd,int next)
{
	struct timeval timeout;
	int ret,i;


	// can timeout until the next tick
	timeout.tv_sec  = next/1000;
	timeout.tv_usec = next%1000*1000;


	memcpy(rfd, &readfds, sizeof(*rfd));
	ret = sSelect(fd_max, rfd, NULL, NULL, &timeout);

	if( ret == SOCKET_ERROR )
	{
		if( sErrno != S_EINTR )
		{
			ShowFatalError("do_sockets: select() failed, error code %d!\n", sErrno);
			exit(EXIT_FAILURE);
		}
		return 0; // interrupted by a signal, just loop and try again
	}

	last_tick = time(NULL);

#if defined(WIN32)
	// on windows, enumerating all members of the fd_set is way faster if we access the internals
	for( i = 0; i < (int)rfd->fd_count; ++i )
	{
		int fd = sock2fd(rfd->fd_array[i]);
		if( session[fd] )
		{
			session[fd]->func_recv(fd);

			if( fd != login_fd &&
				fd != login_lobbydata_fd &&
				fd != login_lobbyview_fd  )
			{
				session[fd]->func_parse(fd);

				if(!session[fd])
					continue;

//				RFIFOFLUSH(fd);
			}
		}
	}
#else
	// otherwise assume that the fd_set is a bit-array and enumerate it in a standard way
	for( i = 1; ret && i < fd_max; ++i )
	{
		if(sFD_ISSET(i,rfd) && session[i])
		{
			session[i]->func_recv(i);

			if( session[i] )
			{

					if(     i != login_fd &&
						i != login_lobbydata_fd &&
						i != login_lobbyview_fd  )
						{
							session[i]->func_parse(i);

							if(!session[i])
							continue;

//							RFIFOFLUSH(fd);
						}
					--ret;
				}
		}
	}
#endif

	/*
		// parse input data on each socket
	for(i = 1; i < fd_max; i++)
	{
		if(!session[i])
			continue;

		if (session[i]->rdata_tick && DIFF_TICK(last_tick, session[i]->rdata_tick) > stall_time) {
			ShowInfo("Session #%d timed out\n", i);
			set_eof(i);
		}

		session[i]->func_parse(i);

		if(!session[i])
			continue;

		// after parse, check client's RFIFO size to know if there is an invalid packet (too big and not parsed)
		if (session[i]->rdata_size == RFIFO_SIZE && session[i]->max_rdata == RFIFO_SIZE) {
			set_eof(i);
			continue;
		}
		RFIFOFLUSH(i);
	}*/


	for (i = 1; i < fd_max; i++)
	{
		if(!session[i])
			continue;

		if(session[i]->wdata_size)
			session[i]->func_send(i);
	}
	return 0;
}
/*! 
 *  \brief     Start Char Server
 *  \details   Start the char-server and load the confs
 *  \author    Fimbulwinter Development Team
 *  \author    GreenBox
 *  \date      08/12/11
 *
 **/
void CharServer::run()
{
	io_service = new boost::asio::io_service();

	// Read Config Files
	try
	{
		char_config = new config_file("./Config/charserver.conf");
		{
			config.server_name = char_config->read<string>("server.name", "Cronus++");

			config.network_bindip = char_config->read<string>("network.bindip", "0.0.0.0");
			config.network_bindport = char_config->read<unsigned short>("network.bindport", 6121);

			config.network_charip = char_config->read<string>("network.charip", "");

			config.inter_login_ip = char_config->read<string>("inter.login.ip", "127.0.0.1");
			config.inter_login_port = char_config->read<unsigned short>("inter.login.port", 6900);
			config.inter_login_user = char_config->read<string>("inter.login.user", "s1");
			config.inter_login_pass = char_config->read<string>("inter.login.pass", "p1");

			if (config.network_charip == "")
			{
				ShowInfo("Auto-detecting my IP Address...\n");
				
				tcp::resolver resolver(*io_service);
				tcp::resolver::query query(boost::asio::ip::host_name(), "");
				tcp::resolver::iterator iter = resolver.resolve(query);
				tcp::resolver::iterator end;

				while (iter != end)
				{
					tcp::endpoint ep = *iter++;

					if (!ep.address().is_v4())
						continue;
					
					config.network_charip = ep.address().to_string();

					break;
				}

				ShowStatus("Defaulting our IP Address to %s...\n", config.network_charip.c_str());
			}
		}
		ShowStatus("Finished reading charserver.conf.\n");
	}
	catch (config_file::file_not_found *fnf)
	{
		ShowFatalError("Config file not found: %s.\n", fnf->filename);
		return;
	}

	TimerManager::Initialize(io_service);
	
	if (!maps.load("./Data/map_index"))
	{
		getchar();
		abort();
	}

	// Initialize Database System
	{
		ShowInfo("Opening connection to database...\n");

		try
		{
			database = database_helper::get_session(char_config);
		}
		catch (soci::soci_error err)
		{
			ShowFatalError("Error opening database connection: %s\n", err.what());
			return;
		}

		chars = new CharDB(database);

		ShowSQL("Successfully opened database connection.\n");
	}

	connect_to_auth();

	// Initialize Network System
	{
		boost::system::error_code err;
		address_v4 bindip = address_v4::from_string(config.network_bindip, err);

		if (err)
		{
			ShowFatalError("%s\n", err.message().c_str());
			return;
		}

		server = new tcp_server(*io_service, (address)bindip, config.network_bindport);
		server->set_default_parser(CharServer::parse_from_client);

		ShowStatus("CharServer is ready and listening on %s:%d.\n", config.network_bindip.c_str(), config.network_bindport);
	}

	// Run IO service service and start pooling events
	io_service->run();
}
Beispiel #16
0
void *_mmalloc (size_t size, const char *file, int line, const char *func)
{
	struct block *block;
	short size_hash = size2hash (size);
	struct unit_head *head;

	if ( ( (long) size) < 0) {
		ShowError ("_mmalloc: %d\n", size);
		return NULL;
	}

	if (size == 0) {
		return NULL;
	}

	memmgr_usage_bytes += size;

	/* ブロック長を超える領域の確保には、malloc() を用いる */
	/* その際、unit_head.block に NULL を代入して区別する */
	if (hash2size (size_hash) > BLOCK_DATA_SIZE - sizeof (struct unit_head)) {
		struct unit_head_large *p = (struct unit_head_large *) MALLOC (sizeof (struct unit_head_large) + size, file, line, func);

		if (p != NULL) {
			p->size            = size;
			p->unit_head.block = NULL;
			p->unit_head.size  = 0;
			p->unit_head.file  = file;
			p->unit_head.line  = line;
			p->prev = NULL;

			if (unit_head_large_first == NULL)
				p->next = NULL;
			else {
				unit_head_large_first->prev = p;
				p->next = unit_head_large_first;
			}

			unit_head_large_first = p;
			* (long *) ( (char *) p + sizeof (struct unit_head_large) - sizeof (long) + size) = 0xdeadbeaf;
			return (char *) p + sizeof (struct unit_head_large) - sizeof (long);
		} else {
			ShowFatalError ("Memory manager::memmgr_alloc failed (allocating %d+%d bytes at %s:%d).\n", sizeof (struct unit_head_large), size, file, line);
			exit (EXIT_FAILURE);
		}
	}

	/* 同一サイズのブロックが確保されていない時、新たに確保する */
	if (hash_unfill[size_hash]) {
		block = hash_unfill[size_hash];
	} else {
		block = block_malloc (size_hash);
	}

	if (block->unit_unfill == 0xFFFF) {
		// free済み領域が残っていない
		memmgr_assert (block->unit_used <  block->unit_count);
		memmgr_assert (block->unit_used == block->unit_maxused);
		head = block2unit (block, block->unit_maxused);
		block->unit_used++;
		block->unit_maxused++;
	} else {
		head = block2unit (block, block->unit_unfill);
		block->unit_unfill = head->size;
		block->unit_used++;
	}

	if (block->unit_unfill == 0xFFFF && block->unit_maxused >= block->unit_count) {
		// ユニットを使い果たしたので、unfillリストから削除
		if (block->unfill_prev == &block_head) {
			hash_unfill[ size_hash ] = block->unfill_next;
		} else {
			block->unfill_prev->unfill_next = block->unfill_next;
		}

		if (block->unfill_next) {
			block->unfill_next->unfill_prev = block->unfill_prev;
		}

		block->unfill_prev = NULL;
	}

#ifdef DEBUG_MEMMGR
	{
		size_t i, sz = hash2size (size_hash);

		for (i = 0; i < sz; i++) {
			if ( ( (unsigned char *) head) [ sizeof (struct unit_head) - sizeof (long) + i] != 0xfd) {
				if (head->line != 0xfdfd) {
					ShowError ("Memory manager: freed-data is changed. (freed in %s line %d)\n", head->file, head->line);
				} else {
					ShowError ("Memory manager: not-allocated-data is changed.\n");
				}

				break;
			}
		}

		memset ( (char *) head + sizeof (struct unit_head) - sizeof (long), 0xcd, sz);
	}
#endif
	head->block = block;
	head->file  = file;
	head->line  = line;
	head->size  = (unsigned short) size;
	* (long *) ( (char *) head + sizeof (struct unit_head) - sizeof (long) + size) = 0xdeadbeaf;
	return (char *) head + sizeof (struct unit_head) - sizeof (long);
}
//---------------------------------------------------------
// 倉庫データを読み込む
int inter_storage_init()
{
	char line[65536];
	int c=0,tmp_int;
	struct storage *s;
	struct guild_storage *gs;
	FILE *fp;

	storage_db = db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_RELEASE_DATA,sizeof(int));

	fp=fopen(storage_txt,"r");
	if(fp==NULL){
		ShowError("can't read : %s\n",storage_txt);
		return 1;
	}
	while(fgets(line,65535,fp)){
		sscanf(line,"%d",&tmp_int);
		s = (struct storage*)aCalloc(sizeof(struct storage), 1);
		if(s==NULL){
			ShowFatalError("int_storage: out of memory!\n");
			exit(0);
		}
//		memset(s,0,sizeof(struct storage)); aCalloc does this...
		s->account_id=tmp_int;
		if(s->account_id > 0 && storage_fromstr(line,s) == 0) {
			idb_put(storage_db,s->account_id,s);
		}
		else{
			ShowError("int_storage: broken data [%s] line %d\n",storage_txt,c);
			aFree(s);
		}
		c++;
	}
	fclose(fp);

	c = 0;
	guild_storage_db = db_alloc(__FILE__,__LINE__,DB_INT,DB_OPT_RELEASE_DATA,sizeof(int));

	fp=fopen(guild_storage_txt,"r");
	if(fp==NULL){
		ShowError("can't read : %s\n",guild_storage_txt);
		return 1;
	}
	while(fgets(line,65535,fp)){
		sscanf(line,"%d",&tmp_int);
		gs = (struct guild_storage*)aCalloc(sizeof(struct guild_storage), 1);
		if(gs==NULL){
			ShowFatalError("int_storage: out of memory!\n");
			exit(0);
		}
//		memset(gs,0,sizeof(struct guild_storage)); aCalloc...
		gs->guild_id=tmp_int;
		if(gs->guild_id > 0 && guild_storage_fromstr(line,gs) == 0) {
			idb_put(guild_storage_db,gs->guild_id,gs);
		}
		else{
			ShowError("int_storage: broken data [%s] line %d\n",guild_storage_txt,c);
			aFree(gs);
		}
		c++;
	}
	fclose(fp);

	return 0;
}
Beispiel #18
0
void* _mmalloc(size_t size, const char *file, int line, const char *func ) {
	int i;
	struct block *block;
	size_t size_hash;

	if (((long) size) < 0) {
		printf("_mmalloc: %d\n", size);
		return 0;
	}
	
	size_hash = (size+BLOCK_ALIGNMENT-1) / BLOCK_ALIGNMENT;
	if(size == 0) {
		return NULL;
	}
	memmgr_usage_bytes += size;

	/* ブロック長を超える領域の確保には、malloc() を用いる */
	/* その際、unit_head.block に NULL を代入して区別する */
	if(size_hash * BLOCK_ALIGNMENT > BLOCK_DATA_SIZE - sizeof(struct unit_head)) {
		struct unit_head_large* p = (struct unit_head_large*)MALLOC(sizeof(struct unit_head_large)+size,file,line,func);
		if(p != NULL) {
			p->unit_head.block = NULL;
			p->unit_head.size  = size;
			p->unit_head.file  = file;
			p->unit_head.line  = line;
			p->prev = NULL;
			if (unit_head_large_first == NULL)
				p->next = NULL;
			else {
				unit_head_large_first->prev = p;
				p->next = unit_head_large_first;
			}
			unit_head_large_first = p;
			*(int*)((char*)p + sizeof(struct unit_head_large) - sizeof(int) + size) = 0xdeadbeaf;
			return (char *)p + sizeof(struct unit_head_large) - sizeof(int);
		} else {
			ShowFatalError("Memory manager::memmgr_alloc failed (allocating %d+%d bytes at %s:%d).\n", sizeof(struct unit_head_large), size, file, line);
			exit(1);
		}
	}

	/* 同一サイズのブロックが確保されていない時、新たに確保する */
	if(unit_unfill[size_hash] == NULL) {
		block = block_malloc();
		if(unit_first[size_hash] == NULL) {
			/* 初回確保 */
			unit_first[size_hash] = block;
			unit_last[size_hash] = block;
			block->samesize_no = 0;
			block->samesize_prev = NULL;
			block->samesize_next = NULL;
		} else {
			/* 連結作業 */
			unit_last[size_hash]->samesize_next = block;
			block->samesize_no   = unit_last[size_hash]->samesize_no + 1;
			block->samesize_prev = unit_last[size_hash];
			block->samesize_next = NULL;
			unit_last[size_hash] = block;
		}
		unit_unfill[size_hash] = block;
		block->unit_size  = size_hash * BLOCK_ALIGNMENT + sizeof(struct unit_head);
		block->unit_count = (int)(BLOCK_DATA_SIZE / block->unit_size);
		block->unit_used  = 0;
		block->unit_hash  = size_hash;
		/* 未使用Flagを立てる */
		for(i=0;i<block->unit_count;i++) {
			((struct unit_head*)(&block->data[block->unit_size * i]))->block = NULL;
		}
	}
	/* ユニット使用個数加算 */
	block = unit_unfill[size_hash];
	block->unit_used++;

	/* ユニット内を全て使い果たした */
	if(block->unit_count == block->unit_used) {
		do {
			unit_unfill[size_hash] = unit_unfill[size_hash]->samesize_next;
		} while(
			unit_unfill[size_hash] != NULL &&
			unit_unfill[size_hash]->unit_count == unit_unfill[size_hash]->unit_used
		);
	}

	/* ブロックの中の空きユニット捜索 */
	for(i=0;i<block->unit_count;i++) {
		struct unit_head *head = (struct unit_head*)(&block->data[block->unit_size * i]);
		if(head->block == NULL) {
			head->block = block;
			head->size  = size;
			head->line  = line;
			head->file  = file;
			*(int*)((char*)head + sizeof(struct unit_head) - sizeof(int) + size) = 0xdeadbeaf;
			return (char *)head + sizeof(struct unit_head) - sizeof(int);
		}
	}
	// ここに来てはいけない。
	ShowFatalError("Memory manager::memmgr_malloc() serious error (allocating %d+%d bytes at %s:%d)\n", sizeof(struct unit_head_large), size, file, line);
	memmgr_info();
	exit(1);
	return NULL;
};
Beispiel #19
0
// パーティ脱退要求
int mapif_parse_PartyLeave(int fd,int party_id,int account_id)
{
	char t_member[2*NAME_LENGTH];
	struct party *p = party_pt;
	if (p == NULL) {
		ShowFatalError("int_party: out of memory !\n");
		return 0;
	}

	inter_party_fromsql(party_id, p);
	if (p->party_id >= 0) {
		int i;
		for (i = 0; i < MAX_PARTY; i++) {
			if (p->member[i].account_id == account_id) {
				mapif_party_leaved(party_id, account_id, p->member[i].name);

				// Update char information, does the name need encoding?
				sprintf (tmp_sql, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d' AND `name`='%s'",
					char_db, party_id, jstrescapecpy(t_member,p->member[i].name));
				if (mysql_query (&mysql_handle, tmp_sql)) {
					ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
					ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
				}

				if (p->member[i].leader == 1){
					int j;
					for (j = 0; j < MAX_PARTY; j++) {
						if (p->member[j].account_id > 0 && j != i) {
							mapif_party_leaved(party_id, p->member[j].account_id, p->member[j].name);
						}
					}
					// we'll skip name-checking and just reset everyone with the same party id [celest]
					// -- if anything goes wrong just uncomment the section above ^^;
					sprintf (tmp_sql, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", char_db, party_id);
					if (mysql_query(&mysql_handle, tmp_sql)) {
						ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
						ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
					}
					// Delete the party, if has no member.
					sprintf(tmp_sql, "DELETE FROM `%s` WHERE `party_id`='%d'", party_db, party_id);
					if (mysql_query(&mysql_handle, tmp_sql)) {
						ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
						ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
					}
					memset(p, 0, sizeof(struct party));
				} else
					memset(&p->member[i], 0, sizeof(struct party_member));
				break;
			}
		}

		if (party_check_empty(p) == 0)
			mapif_party_info(-1,p);// まだ人がいるのでデータ送信
		//else
		//	inter_party_tosql(party_id,p);	// Break the party if no member
	} else {
		sprintf(tmp_sql, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d' AND `account_id`='%d' AND `online`='1'",
			char_db, party_id, account_id);
		if (mysql_query(&mysql_handle, tmp_sql)) {
			ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
		}
	}
	return 0;
}