commit x64 compilation from lulu cause the other branch dont seems to compile properly at home

This commit is contained in:
2026-07-17 16:08:20 +02:00
parent c0f3eeb00d
commit 0efa4ee6f7
625 changed files with 117283 additions and 4426 deletions

View File

@ -0,0 +1,325 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "io_net/io_net_server.h"
#include "metafile/nml.h"
#include "async/task_loop.h"
#include "platform.h"
#include "log/log.h"
using namespace GS::IO;
// #define VERBOSE_LOG
// @FIXME Rewrite communication with the controller thread using AsyncCallQueue.
//------------------------------------------------------------------------------
NetServer::Client *NetServer::GetClient(void *peer)
{
ListForeachPtr(Client *, client, clients)
if (client->peer == peer)
return client;
return NULL;
}
int NetServer::GetClientFreeHandleIndex(const Client &client) const
{
int free_id = 0;
ListForeachPtr(ClientHandleInfo *, i, client.handles)
if (i->id >= free_id)
free_id = i->id + 1;
return free_id;
}
Handle *NetServer::GetClientHandle(const Client &client, int id) const
{
ListForeachPtr(ClientHandleInfo *, i, client.handles)
if (i->id == id)
return i->handle;
return NULL;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
bool NetServer::ProcessCloseCommand(Client &client, GS::StringList &args)
// Close,handle_id
{
if (args.GetCount() != 2)
return false;
int id = args[1].Integer();
ClientHandleInfo *hi = NULL;
ListForeachPtr(ClientHandleInfo *, i, client.handles)
if (i->id == id)
{
hi = i;
break;
}
if (hi == NULL)
return false;
client.handles.Remove(hi);
#ifdef VERBOSE_LOG
__LOG__ << "IO::NetServer: Close handle " << id << " (client total: " << client.handles.GetCount() << ").\n";
#endif
return SendString(client.peer, "Success");
}
bool NetServer::ProcessReadCommand(Client &client, GS::StringList &args)
// Read,size,handle_id
{
if (args.GetCount() != 3)
return false;
Handle *h = GetClientHandle(client, args[2].Integer());
if (h == NULL)
return false;
// Read data.
size_t size = size_t(args[1].Integer());
Array <char> data(size);
size_t read_size = h->Read((void *)data, size);
// Format answer data (FIXME two allocations are not required for this).
String answer = String::Format("Success,%d,", read_size);
Array <char> answer_data(answer.Len() + read_size);
Memory::Copy(answer_data.c_ptr(), answer.c_str(), answer.Len());
Memory::Copy(answer_data.c_ptr() + answer.Len(), data.c_ptr(), read_size);
return Send(client.peer, (void *)answer_data.c_ptr(), answer_data.GetSize());
}
bool NetServer::ProcessSeekCommand(Client &client, GS::StringList &args)
// Seek,offset_from_start,ref,handle_id
{
if (args.GetCount() != 4)
return false;
Handle *h = GetClientHandle(client, args[3].Integer());
if (h == NULL)
return false;
ptrdiff_t offset = ptrdiff_t(args[1].Integer());
Base::SeekRef seek_ref;
if (args[2] == "Start")
seek_ref = Base::SeekStart;
else if (args[2] == "Current")
seek_ref = Base::SeekCurrent;
else if (args[2] == "End")
seek_ref = Base::SeekEnd;
else
return false;
size_t r = h->Seek(offset, seek_ref);
return SendString(client.peer, String::Format("Success,%d", r));
}
bool NetServer::ProcessTellCommand(Client &client, GS::StringList &args)
// Tell,handle_id
{
if (args.GetCount() != 2)
return false;
Handle *h = GetClientHandle(client, args[1].Integer());
if (h == NULL)
return false;
return SendString(client.peer, String::Format("Success,%d", h->Tell()));
}
bool NetServer::ProcessOpenCommand(Client &client, GS::StringList &args)
// Open,path
{
if (args.GetCount() != 2)
__ERR__(__LOG_E__ << "NetServer::ProcessOpenCommand(): incorrect argument count.\n", false)
int index = GetClientFreeHandleIndex(client);
AutoPtr <ClientHandleInfo> i(new ClientHandleInfo);
i->id = index;
i->name = args[1];
i->handle = basefs->Open(i->name);
if (i->handle.IsNull())
return false; // __ERR__(__LOG_E__ << "NetServer::ProcessOpenCommand(): failed to open '" << i->name << "' on base filesystem.\n", false)
client.handles.Add(i.Detach());
#ifdef VERBOSE_LOG
__LOG__ << "IO::NetServer: Open handle '" << args[1] << "' => " << index << " (client total: " << client.handles.GetCount() << ").\n";
#endif
return SendString(client.peer, String::Format("Success,%d", index));
}
bool NetServer::ProcessHashCommand(Client &client, GS::StringList &args)
// Hash,path
{
if (args.GetCount() != 2)
return false;
String hash = basefs->Hash(args[1]);
if (hash.IsEmpty())
return false;
return SendString(client.peer, String::Format("Success,%s", hash.c_str()));
}
bool NetServer::ProcessClientRequest(Client &client, const GS::String &data)
{
StringList args;
data.Split(",", args);
bool r = false;
// Command dispatch.
if (args[0] == "Open")
r = ProcessOpenCommand(client, args);
else if (args[0] == "Seek")
r = ProcessSeekCommand(client, args);
else if (args[0] == "Tell")
r = ProcessTellCommand(client, args);
else if (args[0] == "Read")
r = ProcessReadCommand(client, args);
else if (args[0] == "Close")
r = ProcessCloseCommand(client, args);
else if (args[0] == "Hash")
r = ProcessHashCommand(client, args);
if (!r)
SendString(client.peer, "Failed");
return r;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void NetServer::GetStatistics(Statistics &stats)
{
Time t = Platform::Get().GetTime();
stats.connected = asbool(clients.GetCount());
Network::Enet::Statistics enet_stats;
Network::Enet::GetStatistics(enet_stats);
if ((t - bandwidth_measure.time).toSec() > 2)
{
bandwidth = int((enet_stats.sent_data - bandwidth_measure.value) / (t - bandwidth_measure.time).toSec());
bandwidth_measure.time = t;
bandwidth_measure.value = enet_stats.sent_data;
}
stats.sent_data = enet_stats.sent_data;
stats.bandwidth = bandwidth;
stats.packet_loss = 0;
if (clients.GetCount() > 0)
{
ListForeachPtr(Client *, client, clients)
stats.packet_loss += GetPeerPacketLossRatio(client->peer);
stats.packet_loss /= clients.GetCount();
}
// Handle statistics.
int handle_count = 0;
ListForeachPtr(Client *, client, clients)
handle_count += client->handles.GetCount();
if (stats.handles.Allocate(handle_count))
{
handle_count = 0;
ListForeachPtr(Client *, client, clients)
ListForeachPtr(ClientHandleInfo *, i, client->handles)
{
Statistics::Handle *h = &stats.handles[handle_count++];
h->name = i->name;
}
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void NetServer::OnPeerConnection(void *peer)
{
__LOG_H__ << "IO::NetServer: OnPeerConnection\n";
__ASSERT__(GetClient(peer) == NULL);
clients.Add(new Client(peer));
SetPeerTimeout(peer, TimeoutVeryLong);
}
void NetServer::OnPacketReceived(void *peer, const void *data, size_t size)
{
Client *client = GetClient(peer);
__ASSERT__(client != NULL);
if (size > 512)
{
SendString(peer, "DataLengthError");
return; // invalid
}
String command((char *)data, (char *)data + size);
if (client->handshake_step == -1)
ProcessClientRequest(*client, command);
else
{
switch (client->handshake_step)
{
case 0:
if (command == "RequestIOAccess")
{
__LOG_V__ << "Granting client access.\n";
client->handshake_step = -1;
SendString(peer, "Granted");
}
else
Disconnect(peer);
break;
}
}
}
void NetServer::OnConnectionClosed(void *peer)
{
__LOG_H__ << "IO::NetServer: OnConnectionClosed\n";
Client *client = GetClient(peer);
__ASSERT__(client != NULL);
clients.Remove(client);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
bool NetServer::Start(const char *ip, int port)
{
__LOG_H__ << "IO::NetServer: Starting on " << ip << " port " << port << ".\n";
return OpenServer(ip, port);
}
void NetServer::Stop()
{
__LOG_H__ << "IO::NetServer: Shutting down.\n";
// Disconnect all clients.
ListForeachPtr(Client *, c, clients)
Disconnect(c->peer);
StartTaskLoop(clients.GetCount() > 0, 2000)
{
UpdateHost();
Platform::Get().Sleep(1);
}
EndTaskLoop
Close();
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
NetServer::NetServer(Base *fs) : basefs(fs), bandwidth(0)
{}
NetServer::~NetServer()
{ Stop(); }
//------------------------------------------------------------------------------