Experimental node stuff
This commit is contained in:
parent
73ed335b11
commit
da74627af3
@ -12,6 +12,7 @@ namespace Components
|
|||||||
Loader::Register(new Dvar());
|
Loader::Register(new Dvar());
|
||||||
Loader::Register(new Maps());
|
Loader::Register(new Maps());
|
||||||
Loader::Register(new News());
|
Loader::Register(new News());
|
||||||
|
Loader::Register(new Node());
|
||||||
Loader::Register(new Menus());
|
Loader::Register(new Menus());
|
||||||
Loader::Register(new Party());
|
Loader::Register(new Party());
|
||||||
Loader::Register(new Colors());
|
Loader::Register(new Colors());
|
||||||
|
@ -35,6 +35,7 @@ namespace Components
|
|||||||
#include "Modules\IPCPipe.hpp"
|
#include "Modules\IPCPipe.hpp"
|
||||||
#include "Modules\Network.hpp"
|
#include "Modules\Network.hpp"
|
||||||
#include "Modules\Theatre.hpp"
|
#include "Modules\Theatre.hpp"
|
||||||
|
#include "Modules\Node.hpp"
|
||||||
#include "Modules\Party.hpp" // Destroys the order, but requires network classes :D
|
#include "Modules\Party.hpp" // Destroys the order, but requires network classes :D
|
||||||
#include "Modules\Download.hpp"
|
#include "Modules\Download.hpp"
|
||||||
#include "Modules\Playlist.hpp"
|
#include "Modules\Playlist.hpp"
|
||||||
|
@ -7,7 +7,7 @@ namespace Components
|
|||||||
|
|
||||||
bool Logger::IsConsoleReady()
|
bool Logger::IsConsoleReady()
|
||||||
{
|
{
|
||||||
return (IsWindow(*(HWND*)0x64A3288) != FALSE);
|
return (IsWindow(*(HWND*)0x64A3288) != FALSE || (Dedicated::IsDedicated() && !Flags::HasFlag("console")));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::Print(const char* message, ...)
|
void Logger::Print(const char* message, ...)
|
||||||
|
@ -79,6 +79,8 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Check the external IP as well!
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
300
src/Components/Modules/Node.cpp
Normal file
300
src/Components/Modules/Node.cpp
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
#include "STDInclude.hpp"
|
||||||
|
|
||||||
|
namespace Components
|
||||||
|
{
|
||||||
|
std::vector<Node::NodeEntry> Node::Nodes;
|
||||||
|
std::vector<Node::DediEntry> Node::Dedis;
|
||||||
|
|
||||||
|
void Node::LoadNodes()
|
||||||
|
{
|
||||||
|
std::string nodes = Utils::ReadFile("nodes.txt");
|
||||||
|
auto list = Utils::Explode(nodes, '\n');
|
||||||
|
|
||||||
|
for (auto entry : list)
|
||||||
|
{
|
||||||
|
Network::Address addr(entry);
|
||||||
|
Node::AddNode(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::LoadDedis()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::StoreNodes()
|
||||||
|
{
|
||||||
|
std::string nodes;
|
||||||
|
|
||||||
|
for (auto node : Node::Nodes)
|
||||||
|
{
|
||||||
|
nodes.append(node.address.GetString());
|
||||||
|
nodes.append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils::WriteFile("nodes.txt", nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::StoreDedis()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::AddNode(Network::Address address, bool valid)
|
||||||
|
{
|
||||||
|
//if (address.IsLocal() || address.IsSelf()) return;
|
||||||
|
|
||||||
|
Node::NodeEntry entry;
|
||||||
|
|
||||||
|
entry.startTime = 0;
|
||||||
|
entry.endTime = (valid ? Game::Com_Milliseconds() : 0);
|
||||||
|
entry.state = (valid ? Node::STATE_VALID : Node::STATE_UNKNOWN);
|
||||||
|
entry.address = address;
|
||||||
|
|
||||||
|
// Search if we already know that node
|
||||||
|
bool duplicate = false;
|
||||||
|
for (auto &ourEntry : Node::Nodes)
|
||||||
|
{
|
||||||
|
if (ourEntry.address == entry.address)
|
||||||
|
{
|
||||||
|
// Validate it
|
||||||
|
if (valid)
|
||||||
|
{
|
||||||
|
ourEntry.state = Node::STATE_VALID;
|
||||||
|
ourEntry.endTime = Game::Com_Milliseconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert if we don't
|
||||||
|
if (!duplicate)
|
||||||
|
{
|
||||||
|
Node::Nodes.push_back(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::AddDedi(Network::Address address)
|
||||||
|
{
|
||||||
|
Node::DediEntry entry;
|
||||||
|
|
||||||
|
entry.startTime = 0;
|
||||||
|
entry.endTime = 0;
|
||||||
|
entry.state = Node::STATE_UNKNOWN;
|
||||||
|
entry.address = address;
|
||||||
|
|
||||||
|
// Search if we already know that node
|
||||||
|
bool duplicate = false;
|
||||||
|
for (auto ourEntry : Node::Nodes)
|
||||||
|
{
|
||||||
|
if (ourEntry.address == entry.address)
|
||||||
|
{
|
||||||
|
duplicate = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert if we don't
|
||||||
|
if (!duplicate)
|
||||||
|
{
|
||||||
|
Node::Dedis.push_back(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::SendNodeList(Network::Address target)
|
||||||
|
{
|
||||||
|
if (target.IsSelf()) return;
|
||||||
|
|
||||||
|
std::vector<Node::AddressEntry> entries;
|
||||||
|
|
||||||
|
for (auto entry : Node::Nodes)
|
||||||
|
{
|
||||||
|
if (entry.state != Node::STATE_INVALID) // Only send valid nodes, or shall we send invalid ones as well?
|
||||||
|
{
|
||||||
|
Node::AddressEntry thisAddress;
|
||||||
|
thisAddress.fromNetAddress(entry.address);
|
||||||
|
|
||||||
|
entries.push_back(thisAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entries.size() >= 111)
|
||||||
|
{
|
||||||
|
std::string packet = "nodeNodeList\n";
|
||||||
|
packet.append(reinterpret_cast<char*>(entries.data()), entries.size() * sizeof(Node::AddressEntry));
|
||||||
|
|
||||||
|
Network::SendRaw(target, packet);
|
||||||
|
|
||||||
|
entries.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string packet = "nodeNodeList\n";
|
||||||
|
packet.append(reinterpret_cast<char*>(entries.data()), entries.size() * sizeof(Node::AddressEntry));
|
||||||
|
|
||||||
|
Network::SendRaw(target, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::SendDediList(Network::Address target)
|
||||||
|
{
|
||||||
|
if (target.IsSelf()) return;
|
||||||
|
|
||||||
|
std::vector<Node::AddressEntry> entries;
|
||||||
|
|
||||||
|
for (auto entry : Node::Dedis)
|
||||||
|
{
|
||||||
|
if (entry.state == Node::STATE_VALID) // Only send valid dedis
|
||||||
|
{
|
||||||
|
Node::AddressEntry thisAddress;
|
||||||
|
thisAddress.fromNetAddress(entry.address);
|
||||||
|
|
||||||
|
entries.push_back(thisAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string packet = "nodeDediList\n";
|
||||||
|
packet.append(reinterpret_cast<char*>(entries.data()), entries.size() * sizeof(Node::AddressEntry));
|
||||||
|
|
||||||
|
Network::SendRaw(target, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::Node()
|
||||||
|
{
|
||||||
|
#ifdef USE_NODE_STUFF
|
||||||
|
Assert_Size(Node::AddressEntry, 6);
|
||||||
|
|
||||||
|
Dvar::OnInit([] ()
|
||||||
|
{
|
||||||
|
Node::Nodes.clear();
|
||||||
|
Node::LoadNodes();
|
||||||
|
|
||||||
|
Node::Dedis.clear();
|
||||||
|
Node::LoadDedis();
|
||||||
|
});
|
||||||
|
|
||||||
|
Network::Handle("nodeRequestLists", [] (Network::Address address, std::string data)
|
||||||
|
{
|
||||||
|
Logger::Print("Sending our lists to %s\n", address.GetString());
|
||||||
|
|
||||||
|
// Consider this a node for now!
|
||||||
|
//Node::AddNode(address, true);
|
||||||
|
|
||||||
|
Node::SendNodeList(address);
|
||||||
|
//Node::SendDediList(address);
|
||||||
|
});
|
||||||
|
|
||||||
|
Network::Handle("nodeNodeList", [] (Network::Address address, std::string data)
|
||||||
|
{
|
||||||
|
if (data.size() % sizeof(Node::AddressEntry))
|
||||||
|
{
|
||||||
|
Logger::Print("Received invalid node list from %s!\n", address.GetString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int size = (data.size() / sizeof(Node::AddressEntry));
|
||||||
|
|
||||||
|
Logger::Print("Received valid node list with %d entries from %s\n", size, address.GetString());
|
||||||
|
|
||||||
|
// Insert the node itself and mark it as valid
|
||||||
|
Node::AddNode(address, true);
|
||||||
|
|
||||||
|
Node::AddressEntry* addresses = reinterpret_cast<Node::AddressEntry*>(const_cast<char*>(data.data()));
|
||||||
|
for (unsigned int i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
Node::AddNode(addresses[i].toNetAddress());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Network::Handle("nodeDediList", [] (Network::Address address, std::string data)
|
||||||
|
{
|
||||||
|
if (data.size() % sizeof(Node::AddressEntry))
|
||||||
|
{
|
||||||
|
Logger::Print("Received invalid dedi list from %s!\n", address.GetString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int size = (data.size() / sizeof(Node::AddressEntry));
|
||||||
|
|
||||||
|
Logger::Print("Received valid dedi list with %d entries from %s\n", size, address.GetString());
|
||||||
|
|
||||||
|
// Insert the node and mark it as valid
|
||||||
|
Node::AddNode(address, true);
|
||||||
|
|
||||||
|
Node::AddressEntry* addresses = reinterpret_cast<Node::AddressEntry*>(const_cast<char*>(data.data()));
|
||||||
|
for (unsigned int i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
Node::AddDedi(addresses[i].toNetAddress());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Dedicated::OnFrame([] ()
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
// Send requests
|
||||||
|
for (auto &node : Node::Nodes)
|
||||||
|
{
|
||||||
|
// Frame limit
|
||||||
|
if (count >= 1) break; // Query only 1 node per frame (-> 3 packets sent per frame)
|
||||||
|
|
||||||
|
if (node.state == Node::STATE_UNKNOWN || (/*node.state != Node::STATE_INVALID && */node.state != Node::STATE_QUERYING && (Game::Com_Milliseconds() - node.endTime) > (1000 * 30)))
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
|
||||||
|
node.startTime = Game::Com_Milliseconds();
|
||||||
|
node.endTime = 0;
|
||||||
|
node.state = Node::STATE_QUERYING;
|
||||||
|
|
||||||
|
Logger::Print("Syncing with node %s...\n", node.address.GetString());
|
||||||
|
|
||||||
|
// Request new lists
|
||||||
|
Network::Send(node.address, "nodeRequestLists");
|
||||||
|
|
||||||
|
// Send our lists
|
||||||
|
Node::SendNodeList(node.address);
|
||||||
|
//Node::SendDediList(node.address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark invalid nodes
|
||||||
|
for (auto &node : Node::Nodes)
|
||||||
|
{
|
||||||
|
if (node.state == Node::STATE_QUERYING && (Game::Com_Milliseconds() - node.startTime) > (1000 * 10))
|
||||||
|
{
|
||||||
|
node.state = Node::STATE_INVALID;
|
||||||
|
node.endTime = Game::Com_Milliseconds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
Command::Add("listnodes", [] (Command::Params params)
|
||||||
|
{
|
||||||
|
Logger::Print("Nodes: %d\n", Node::Nodes.size());
|
||||||
|
|
||||||
|
for (auto node : Node::Nodes)
|
||||||
|
{
|
||||||
|
Logger::Print("%s\n", node.address.GetString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Command::Add("addnode", [](Command::Params params)
|
||||||
|
{
|
||||||
|
if (params.Length() < 2) return;
|
||||||
|
|
||||||
|
Node::AddNode(Network::Address(params[1]));
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::~Node()
|
||||||
|
{
|
||||||
|
Node::StoreNodes();
|
||||||
|
Node::Nodes.clear();
|
||||||
|
|
||||||
|
Node::StoreDedis();
|
||||||
|
Node::Dedis.clear();
|
||||||
|
}
|
||||||
|
}
|
75
src/Components/Modules/Node.hpp
Normal file
75
src/Components/Modules/Node.hpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
namespace Components
|
||||||
|
{
|
||||||
|
class Node : public Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Node();
|
||||||
|
~Node();
|
||||||
|
const char* GetName() { return "Node"; };
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum EntryState
|
||||||
|
{
|
||||||
|
STATE_UNKNOWN,
|
||||||
|
STATE_QUERYING,
|
||||||
|
STATE_VALID,
|
||||||
|
STATE_INVALID
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NodeEntry
|
||||||
|
{
|
||||||
|
Network::Address address;
|
||||||
|
EntryState state;
|
||||||
|
int startTime;
|
||||||
|
int endTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DediEntry
|
||||||
|
{
|
||||||
|
Network::Address address;
|
||||||
|
EntryState state;
|
||||||
|
int startTime;
|
||||||
|
int endTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
struct AddressEntry
|
||||||
|
{
|
||||||
|
Game::netIP_t ip;
|
||||||
|
unsigned short port;
|
||||||
|
|
||||||
|
Network::Address toNetAddress()
|
||||||
|
{
|
||||||
|
Network::Address address;
|
||||||
|
|
||||||
|
address.SetIP(this->ip);
|
||||||
|
address.SetPort(ntohs(this->port));
|
||||||
|
address.SetType(Game::netadrtype_t::NA_IP);
|
||||||
|
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fromNetAddress(Network::Address address)
|
||||||
|
{
|
||||||
|
this->ip = address.GetIP();
|
||||||
|
this->port = htons(address.GetPort());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
static std::vector<NodeEntry> Nodes;
|
||||||
|
static std::vector<DediEntry> Dedis;
|
||||||
|
|
||||||
|
static void LoadNodes();
|
||||||
|
static void LoadDedis();
|
||||||
|
|
||||||
|
static void StoreNodes();
|
||||||
|
static void StoreDedis();
|
||||||
|
|
||||||
|
static void AddNode(Network::Address address, bool valid = false);
|
||||||
|
static void AddDedi(Network::Address address);
|
||||||
|
|
||||||
|
static void SendNodeList(Network::Address target);
|
||||||
|
static void SendDediList(Network::Address target);
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user