示例#1
0
	virtual int Save()
	{
		if(!m_pStorage)
			return -1;

		// try to open file
		IOHANDLE File = m_pStorage->OpenFile("masters.cfg", IOFLAG_WRITE, IStorageTW::TYPE_SAVE);
		if(!File)
			return -1;

		for(int i = 0; i < MAX_MASTERSERVERS; i++)
		{
			char aAddrStr[NETADDR_MAXSTRSIZE];
			if(m_aMasterServers[i].m_Addr.type != NETTYPE_INVALID)
				net_addr_str(&m_aMasterServers[i].m_Addr, aAddrStr, sizeof(aAddrStr));
			else
				aAddrStr[0] = 0;
			char aBuf[256];
			str_format(aBuf, sizeof(aBuf), "%s %s\n", m_aMasterServers[i].m_aHostname, aAddrStr);

			io_write(File, aBuf, str_length(aBuf));
		}

		io_close(File);
		return 0;
	}
示例#2
0
	virtual int Load()
	{
		if(!m_pStorage)
			return -1;

		// try to open file
		IOHANDLE File = m_pStorage->OpenFile("masters.cfg", IOFLAG_READ, IStorageTW::TYPE_SAVE);
		if(!File)
			return -1;

		CLineReader LineReader;
		LineReader.Init(File);
		while(1)
		{
			CMasterInfo Info = {{0}};
			const char *pLine = LineReader.Get();
			if(!pLine)
				break;

			// parse line
			char aAddrStr[NETADDR_MAXSTRSIZE];
			if(sscanf(pLine, "%127s %47s", Info.m_aHostname, aAddrStr) == 2 && net_addr_from_str(&Info.m_Addr, aAddrStr) == 0)
			{
				Info.m_Addr.port = 8300;
				bool Added = false;
				for(int i = 0; i < MAX_MASTERSERVERS; ++i)
					if(str_comp(m_aMasterServers[i].m_aHostname, Info.m_aHostname) == 0)
					{
						m_aMasterServers[i] = Info;
						Added = true;
						break;
					}

				if(!Added)
				{
					for(int i = 0; i < MAX_MASTERSERVERS; ++i)
						if(m_aMasterServers[i].m_Addr.type == NETTYPE_INVALID)
						{
							m_aMasterServers[i] = Info;
							Added = true;
							break;
						}
				}

				if(!Added)
					break;
			}
		}

		io_close(File);
		return 0;
	}
示例#3
0
void CServerBrowser::SaveCache()
{
	// nothing to save
	if(m_NumServers < 1)
		return;

	IStorageTW *pStorage = Kernel()->RequestInterface<IStorageTW>();

	// open file
	IOHANDLE File = pStorage->OpenFile("tmp/cache/serverlist", IOFLAG_WRITE, IStorageTW::TYPE_SAVE);
	if(!File)
	{
		dbg_msg("browser", "failed to open cache file for writing");
		m_CacheExists = false;
		return;
	}

	// save version of serverlist cache file
	{ char v = CACHE_VERSION; io_write(File, &v, 1); } // save version of cachefile

	// save number of servers
	io_write(File, &m_NumServers, sizeof(m_NumServers)); // save number of servers

	// save array length
	io_write(File, &m_NumServerCapacity, sizeof(m_NumServerCapacity)); // save length of array

	// save all the infos
	for(int i = 0; i < m_NumServers; i++)
	{
		const CServerInfo Info = m_ppServerlist[i]->m_Info;

		//dbg_msg("browser", "saving entry %i %s %s", i, pInfo->m_aAddress, pInfo->m_aName);
		io_write(File, &Info, sizeof(CServerInfo));
	}

	io_close(File); // TODO: check if saving actually succeeded

	if(g_Config.m_Debug)
		dbg_msg("browser", "successfully saved serverlist with %i entries", m_NumServers);
	m_CacheExists = true;
}
示例#4
0
void CServerBrowser::LoadCacheThread(void *pUser)
{
	CServerBrowser *pSelf = (CServerBrowser *)pUser;
	IStorageTW *pStorage = pSelf->Kernel()->RequestInterface<IStorageTW>();

	int64 StartTime = time_get();

	// clear out everything
	pSelf->m_ServerlistHeap.Reset();
	pSelf->m_NumServers = 0;
	pSelf->m_NumSortedServers = 0;
	mem_zero(pSelf->m_aServerlistIp, sizeof(pSelf->m_aServerlistIp));
	pSelf->m_pFirstReqServer = 0;
	pSelf->m_pLastReqServer = 0;
	pSelf->m_NumRequests = 0;
	pSelf->m_CurrentMaxRequests = g_Config.m_BrMaxRequests;
	pSelf->m_CurrentToken = (pSelf->m_CurrentToken+1)&0xff;
	pSelf->m_ServerlistType = IServerBrowser::TYPE_INTERNET;

	// open file
	IOHANDLE File = pStorage->OpenFile("tmp/cache/serverlist", IOFLAG_READ, IStorageTW::TYPE_ALL);
	if(!File)
	{
		dbg_msg("browser", "opening cache file failed.");
		pSelf->m_CacheExists = false;
		pSelf->m_ServerdataLocked = false;
		return;// false;
	}

	// get version
	{
		char v; io_read(File, &v, 1);
		if(g_Config.m_Debug)
			dbg_msg("browser", "loading serverlist from cache...");
		if(v != CACHE_VERSION)
			dbg_msg("cache", "file version doesn't match, we may fail! (%i != %i)", v, CACHE_VERSION);
	}

	// get number of servers
	int NumServers = 0;
	io_read(File, &NumServers, sizeof(NumServers));
	//dbg_msg("browser", "serverlist cache entries: %i", NumServers);

	mem_zero(pSelf->m_ppServerlist, pSelf->m_NumServerCapacity);

	// get length of array
	io_read(File, &pSelf->m_NumServerCapacity, sizeof(pSelf->m_NumServerCapacity));

	// get rid of current serverlist and create a new one
	mem_free(pSelf->m_ppServerlist);
	pSelf->m_ppServerlist = (CServerEntry **)mem_alloc(pSelf->m_NumServerCapacity*sizeof(CServerEntry*), 1);

	// read the data from the file into the serverlist
	CServerInfo *pServerInfos = (CServerInfo*)mem_alloc(sizeof(CServerInfo)*NumServers, 0);
	io_read(File, pServerInfos, sizeof(CServerInfo)*NumServers);
	io_close(File);

	for(int i = 0; i < NumServers; i++)
	{
		NETADDR Addr;
		net_addr_from_str(&Addr, pServerInfos[i].m_aAddress);
		//dbg_msg("browser", "loading %i %s %s", i, Info.m_aAddress, Info.m_aName);
		pSelf->Set(Addr, IServerBrowser::SET_TOKEN, pSelf->m_CurrentToken, &pServerInfos[i]);
	}
	mem_free(pServerInfos);

	if(g_Config.m_Debug)
		dbg_msg("browser", "successfully loaded serverlist cache with %i entries (total %i), took %.2fms", pSelf->m_NumServers, NumServers, ((time_get()-StartTime)*1000)/(float)time_freq()); // TODO: check if saving actually succeeded
	//m_NeedUpgrade = true; // disabled due to sending our ip out to the whole universe
	pSelf->m_ServerdataLocked = false;
	pSelf->Sort(true);
	return;// true;
}
示例#5
0
void CServerBrowser::LoadDDNet()
{
	// reset servers / countries
	m_NumDDNetCountries = 0;
	m_NumDDNetTypes = 0;

	// load ddnet server list
	IStorageTW *pStorage = Kernel()->RequestInterface<IStorageTW>();
	IOHANDLE File = pStorage->OpenFile("tmp/cache/ddnet-servers.json", IOFLAG_READ, IStorageTW::TYPE_ALL);

	if(File)
	{
		char aBuf[4096*4];
		mem_zero(aBuf, sizeof(aBuf));

		io_read(File, aBuf, sizeof(aBuf));
		io_close(File);


		// parse JSON
		json_value *pCountries = json_parse(aBuf);

		if (pCountries && pCountries->type == json_array)
		{
			for (int i = 0; i < json_array_length(pCountries) && m_NumDDNetCountries < MAX_DDNET_COUNTRIES; i++)
			{
				// pSrv - { name, flagId, servers }
				const json_value *pSrv = json_array_get(pCountries, i);
				const json_value *pTypes = json_object_get(pSrv, "servers");
				const json_value *pName = json_object_get(pSrv, "name");
				const json_value *pFlagID = json_object_get(pSrv, "flagId");

				if (pSrv->type != json_object || pTypes->type != json_object || pName->type != json_string || pFlagID->type != json_integer)
				{
					dbg_msg("client_srvbrowse", "invalid attributes");
					continue;
				}

				// build structure
				CDDNetCountry *pCntr = &m_aDDNetCountries[m_NumDDNetCountries];

				pCntr->Reset();

				str_copy(pCntr->m_aName, json_string_get(pName), sizeof(pCntr->m_aName));
				pCntr->m_FlagID = json_int_get(pFlagID);

				// add country
				for (unsigned int t = 0; t < pTypes->u.object.length; t++)
				{
					const char *pType = pTypes->u.object.values[t].name;
					const json_value *pAddrs = pTypes->u.object.values[t].value;

					// add type
					if(json_array_length(pAddrs) > 0 && m_NumDDNetTypes < MAX_DDNET_TYPES)
					{
						int pos;
						for(pos = 0; pos < m_NumDDNetTypes; pos++)
						{
							if(!str_comp(m_aDDNetTypes[pos], pType))
								break;
						}
						if(pos == m_NumDDNetTypes)
						{
							str_copy(m_aDDNetTypes[m_NumDDNetTypes], pType, sizeof(m_aDDNetTypes[m_NumDDNetTypes]));
							m_NumDDNetTypes++;
						}
					}

					// add addresses
					for (int g = 0; g < json_array_length(pAddrs); g++, pCntr->m_NumServers++)
					{
						const json_value *pAddr = json_array_get(pAddrs, g);
						const char* pStr = json_string_get(pAddr);
						net_addr_from_str(&pCntr->m_aServers[pCntr->m_NumServers], pStr);
						str_copy(pCntr->m_aTypes[pCntr->m_NumServers], pType, sizeof(pCntr->m_aTypes[pCntr->m_NumServers]));
					}
				}

				m_NumDDNetCountries++;
			}
		}

		if (pCountries)
			json_value_free(pCountries);
	}
}