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; }
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; }
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; }
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; }
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); } }