Optimize serverlist.
This commit is contained in:
parent
b6ee7e3ea8
commit
7804e693c2
@ -71,27 +71,26 @@ namespace Components
|
|||||||
ServerList::RefreshContainer.Servers.clear();
|
ServerList::RefreshContainer.Servers.clear();
|
||||||
ServerList::RefreshContainer.Mutex.unlock();
|
ServerList::RefreshContainer.Mutex.unlock();
|
||||||
|
|
||||||
|
ServerList::RefreshContainer.SendCount = 0;
|
||||||
|
ServerList::RefreshContainer.SentCount = 0;
|
||||||
|
|
||||||
int masterPort = Dvar::Var("masterPort").Get<int>();
|
int masterPort = Dvar::Var("masterPort").Get<int>();
|
||||||
const char* masterServerName = Dvar::Var("masterServerName").Get<const char*>();
|
const char* masterServerName = Dvar::Var("masterServerName").Get<const char*>();
|
||||||
|
|
||||||
ServerList::RefreshContainer.Host = Network::Address(Utils::VA("%s:%u", masterServerName, masterPort));
|
ServerList::RefreshContainer.Host = Network::Address(Utils::VA("%s:%u", masterServerName, masterPort));
|
||||||
|
|
||||||
ServerList::RefreshContainer.AwaitingList = true;
|
//Network::Send(ServerList::RefreshContainer.Host, "getservers IW4 145 full empty");
|
||||||
|
Network::Send(ServerList::RefreshContainer.Host, "getservers 0 full empty\n");
|
||||||
Network::Send(ServerList::RefreshContainer.Host, "getservers IW4 145 full empty");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerList::Insert(Network::Address address, Utils::InfoString info)
|
void ServerList::Insert(Network::Address address, Utils::InfoString info)
|
||||||
{
|
{
|
||||||
// Do not enter any new servers, if we are awaiting a new list from the master
|
|
||||||
if (ServerList::RefreshContainer.AwaitingList) return;
|
|
||||||
|
|
||||||
ServerList::RefreshContainer.Mutex.lock();
|
ServerList::RefreshContainer.Mutex.lock();
|
||||||
|
|
||||||
for (auto i = ServerList::RefreshContainer.Servers.begin(); i != ServerList::RefreshContainer.Servers.end(); i++)
|
for (auto i = ServerList::RefreshContainer.Servers.begin(); i != ServerList::RefreshContainer.Servers.end(); i++)
|
||||||
{
|
{
|
||||||
// Our desired server
|
// Our desired server
|
||||||
if (i->Target == address)
|
if (i->Target == address && i->Sent)
|
||||||
{
|
{
|
||||||
// Challenge did not match
|
// Challenge did not match
|
||||||
if (i->Challenge != info.Get("challenge"))
|
if (i->Challenge != info.Get("challenge"))
|
||||||
@ -115,6 +114,16 @@ namespace Components
|
|||||||
server.Ping = (Game::Com_Milliseconds() - i->SendTime);
|
server.Ping = (Game::Com_Milliseconds() - i->SendTime);
|
||||||
server.Addr = address;
|
server.Addr = address;
|
||||||
|
|
||||||
|
// Check if already inserted and remove
|
||||||
|
for (auto j = ServerList::OnlineList.begin(); j != ServerList::OnlineList.end(); j++)
|
||||||
|
{
|
||||||
|
if (j->Addr == address)
|
||||||
|
{
|
||||||
|
ServerList::OnlineList.erase(j);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ServerList::OnlineList.push_back(server);
|
ServerList::OnlineList.push_back(server);
|
||||||
|
|
||||||
ServerList::RefreshContainer.Servers.erase(i);
|
ServerList::RefreshContainer.Servers.erase(i);
|
||||||
@ -123,6 +132,40 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger::Print("Current server count: %d\n", ServerList::OnlineList.size());
|
||||||
|
|
||||||
|
ServerList::RefreshContainer.Mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerList::Frame()
|
||||||
|
{
|
||||||
|
ServerList::RefreshContainer.Mutex.lock();
|
||||||
|
|
||||||
|
// Send requests to 10 servers each frame
|
||||||
|
int SendServers = 10;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < ServerList::RefreshContainer.Servers.size(); i++)
|
||||||
|
{
|
||||||
|
ServerList::Container::ServerContainer* server = &ServerList::RefreshContainer.Servers[i];
|
||||||
|
if (server->Sent) continue;
|
||||||
|
|
||||||
|
// Found server we can send a request to
|
||||||
|
server->Sent = true;
|
||||||
|
SendServers--;
|
||||||
|
|
||||||
|
server->SendTime = Game::Com_Milliseconds();
|
||||||
|
server->Challenge = Utils::VA("%d", server->SendTime);
|
||||||
|
|
||||||
|
ServerList::RefreshContainer.SentCount++;
|
||||||
|
|
||||||
|
Network::Send(server->Target, Utils::VA("getinfo %s\n", server->Challenge.data()));
|
||||||
|
|
||||||
|
// Display in the menu, like in COD4
|
||||||
|
//Logger::Print("Sent %d/%d\n", ServerList::RefreshContainer.SentCount, ServerList::RefreshContainer.SendCount);
|
||||||
|
|
||||||
|
if (SendServers <= 0) break;
|
||||||
|
}
|
||||||
|
|
||||||
ServerList::RefreshContainer.Mutex.unlock();
|
ServerList::RefreshContainer.Mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,14 +175,19 @@ namespace Components
|
|||||||
|
|
||||||
Network::Handle("getServersResponse", [] (Network::Address address, std::string data)
|
Network::Handle("getServersResponse", [] (Network::Address address, std::string data)
|
||||||
{
|
{
|
||||||
if (!ServerList::RefreshContainer.AwaitingList) return; // Only parse if we are awaiting a list
|
|
||||||
if (ServerList::RefreshContainer.Host != address) return; // Only parse from host we sent to
|
if (ServerList::RefreshContainer.Host != address) return; // Only parse from host we sent to
|
||||||
|
|
||||||
ServerList::RefreshContainer.AwaitingList = false;
|
|
||||||
|
|
||||||
ServerList::RefreshContainer.Mutex.lock();
|
ServerList::RefreshContainer.Mutex.lock();
|
||||||
|
|
||||||
ServerList::MasterEntry* entry = (ServerList::MasterEntry*)data.data();
|
int offset = 0;
|
||||||
|
ServerList::MasterEntry* entry = nullptr;
|
||||||
|
|
||||||
|
// Find first entry
|
||||||
|
do
|
||||||
|
{
|
||||||
|
entry = (ServerList::MasterEntry*)(data.data() + offset++);
|
||||||
|
}
|
||||||
|
while (!entry->HasSeparator() && !entry->IsEndToken());
|
||||||
|
|
||||||
for (int i = 0; !entry[i].IsEndToken() && entry[i].HasSeparator(); i++)
|
for (int i = 0; !entry[i].IsEndToken() && entry[i].HasSeparator(); i++)
|
||||||
{
|
{
|
||||||
@ -149,14 +197,24 @@ namespace Components
|
|||||||
serverAddr.Get()->type = Game::NA_IP;
|
serverAddr.Get()->type = Game::NA_IP;
|
||||||
|
|
||||||
ServerList::Container::ServerContainer container;
|
ServerList::Container::ServerContainer container;
|
||||||
container.SendTime = Game::Com_Milliseconds();
|
container.Sent = false;
|
||||||
container.Challenge = Utils::VA("%d", container.SendTime);
|
|
||||||
container.Sent = true;
|
|
||||||
container.Target = serverAddr;
|
container.Target = serverAddr;
|
||||||
|
|
||||||
ServerList::RefreshContainer.Servers.push_back(container);
|
bool alreadyInserted = false;
|
||||||
|
for (auto &server : ServerList::RefreshContainer.Servers)
|
||||||
|
{
|
||||||
|
if (server.Target == container.Target)
|
||||||
|
{
|
||||||
|
alreadyInserted = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Network::Send(container.Target, Utils::VA("getinfo %s\n", container.Challenge.data()));
|
if (!alreadyInserted)
|
||||||
|
{
|
||||||
|
ServerList::RefreshContainer.Servers.push_back(container);
|
||||||
|
ServerList::RefreshContainer.SendCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::Print("Parsed %d servers from master\n", ServerList::RefreshContainer.Servers.size());
|
Logger::Print("Parsed %d servers from master\n", ServerList::RefreshContainer.Servers.size());
|
||||||
@ -165,7 +223,7 @@ namespace Components
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Set default masterServerName + port and save it
|
// Set default masterServerName + port and save it
|
||||||
Utils::Hook::Set<const char*>(0x60AD92, "localhost");
|
//Utils::Hook::Set<const char*>(0x60AD92, "localhost");
|
||||||
Utils::Hook::Set<BYTE>(0x60AD90, Game::dvar_flag::DVAR_FLAG_SAVED); // masterServerName
|
Utils::Hook::Set<BYTE>(0x60AD90, Game::dvar_flag::DVAR_FLAG_SAVED); // masterServerName
|
||||||
Utils::Hook::Set<BYTE>(0x60ADC6, Game::dvar_flag::DVAR_FLAG_SAVED); // masterPort
|
Utils::Hook::Set<BYTE>(0x60ADC6, Game::dvar_flag::DVAR_FLAG_SAVED); // masterPort
|
||||||
|
|
||||||
@ -185,6 +243,9 @@ namespace Components
|
|||||||
{
|
{
|
||||||
Logger::Print("Server list sorting by token: %d\n", token.Get<int>());
|
Logger::Print("Server list sorting by token: %d\n", token.Get<int>());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add frame callback
|
||||||
|
Renderer::OnFrame(ServerList::Frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerList::~ServerList()
|
ServerList::~ServerList()
|
||||||
|
@ -49,8 +49,8 @@ namespace Components
|
|||||||
|
|
||||||
bool IsEndToken()
|
bool IsEndToken()
|
||||||
{
|
{
|
||||||
// End of transmission token
|
// End of transmission or file token
|
||||||
return (Token[0] == 'E' && Token[1] == 'O' && Token[2] == 'T');
|
return (Token[0] == 'E' && Token[1] == 'O' && (Token[2] == 'T' || Token[2] == 'F'));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasSeparator()
|
bool HasSeparator()
|
||||||
@ -70,7 +70,8 @@ namespace Components
|
|||||||
Network::Address Target;
|
Network::Address Target;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool AwaitingList;
|
int SentCount;
|
||||||
|
int SendCount;
|
||||||
Network::Address Host;
|
Network::Address Host;
|
||||||
std::vector<ServerContainer> Servers;
|
std::vector<ServerContainer> Servers;
|
||||||
std::mutex Mutex;
|
std::mutex Mutex;
|
||||||
@ -80,6 +81,8 @@ namespace Components
|
|||||||
static const char* GetServerText(int index, int column);
|
static const char* GetServerText(int index, int column);
|
||||||
static void SelectServer(int index);
|
static void SelectServer(int index);
|
||||||
|
|
||||||
|
static void Frame();
|
||||||
|
|
||||||
static unsigned int CurrentServer;
|
static unsigned int CurrentServer;
|
||||||
static Container RefreshContainer;
|
static Container RefreshContainer;
|
||||||
static std::vector<ServerInfo> OnlineList;
|
static std::vector<ServerInfo> OnlineList;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user