add: make graph author read-only if graph file already has author upon load (resolves #369)

This commit is contained in:
jeefo 2022-09-21 14:47:36 +03:00 committed by GitHub
commit fd7b722fd8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 93 additions and 20 deletions

View file

@ -123,6 +123,7 @@ private:
int cmdNodeUpload ();
int cmdNodeIterateCamp ();
int cmdNodeShowStats ();
int cmdNodeFileInfo ();
private:
int menuMain (int item);

View file

@ -70,7 +70,7 @@ CR_DECLARE_SCOPED_ENUM (StorageOption,
// storage header versions
CR_DECLARE_SCOPED_ENUM (StorageVersion,
Graph = 2,
Graph = 3,
Practice = 1,
Vistable = 1,
Matrix = 1,
@ -122,8 +122,9 @@ struct StorageHeader {
// extension header for graph information
struct ExtenHeader {
char author[32];
int32 mapSize;
char author[32]; // original author of graph
int32 mapSize; // bsp size for checksumming map consistency
char modified[32]; // by whom modified
};
// general waypoint header information structure
@ -262,7 +263,6 @@ private:
int x, y, z;
};
int m_version;
int m_editFlags;
int m_loadAttempts;
int m_cacheNodeIndex;
@ -303,7 +303,12 @@ private:
SmallArray <Path> m_paths;
SmallArray <uint8> m_vistable;
String m_tempStrings;
String m_graphAuthor;
String m_graphModified;
ExtenHeader m_extenHeader {};
StorageHeader m_graphHeader {};
edict_t *m_editor;
public:
@ -385,6 +390,7 @@ public:
void convertCampDirection (Path &path);
void setAutoPathDistance (const float distance);
void showStats ();
void showFileInfo ();
const char *getDataDirectory (bool isMemoryFile = false);
const char *getOldFormatGraphName (bool isMemoryFile = false);
@ -407,7 +413,11 @@ public:
}
StringRef getAuthor () const {
return m_tempStrings;
return m_graphAuthor;
}
StringRef getModifiedBy () const {
return m_graphModified;
}
bool hasChanged () const {
@ -473,7 +483,7 @@ template <typename ...Args> bool BotGraph::raiseLoadingError (bool isGraph, MemF
if (isGraph) {
bots.kickEveryone (true);
m_tempStrings = result;
m_graphAuthor = result;
m_paths.clear ();
}
file.close ();

View file

@ -279,7 +279,8 @@ int BotControl::cmdNode () {
"save",
"load",
"help",
"erase"
"erase",
"fileinfo"
};
// check if cmd is allowed on dedicated server
@ -331,6 +332,7 @@ int BotControl::cmdNode () {
addGraphCmd ("teleport", "teleport [index]", "Teleports player to specified node index.", &BotControl::cmdNodeTeleport);
addGraphCmd ("upload", "upload", "Uploads created graph to graph database.", &BotControl::cmdNodeUpload);
addGraphCmd ("stats", "stats [noarguments]", "Shows the stats about node types on the map.", &BotControl::cmdNodeShowStats);
addGraphCmd ("fileinfo", "fileinfo [noarguments]", "Shows basic information about graph file.", &BotControl::cmdNodeFileInfo);
// add path commands
addGraphCmd ("path_create", "path_create [noarguments]", "Opens and displays path creation menu.", &BotControl::cmdNodePathCreate);
@ -854,13 +856,17 @@ int BotControl::cmdNodeIterateCamp () {
}
int BotControl::cmdNodeShowStats () {
enum args { graph_cmd = 1 };
graph.showStats ();
return BotCommandResult::Handled;
}
int BotControl::cmdNodeFileInfo () {
graph.showFileInfo ();
return BotCommandResult::Handled;
}
int BotControl::menuMain (int item) {
closeMenu (); // reset menu display

View file

@ -1132,6 +1132,23 @@ void BotGraph::showStats () {
ctrl.msg ("Block Hostage Points: %d - Sniper Points: %d", noHostagePoints, sniperPoints);
}
void BotGraph::showFileInfo () {
ctrl.msg ("header:");
ctrl.msg (" magic: %d", m_graphHeader.magic);
ctrl.msg (" version: %d", m_graphHeader.version);
ctrl.msg (" node_count: %d", m_graphHeader.length);
ctrl.msg (" compressed_size: %dkB", m_graphHeader.compressed / 1024);
ctrl.msg (" uncompressed_size: %dkB", m_graphHeader.uncompressed / 1024);
ctrl.msg (" options: %d", m_graphHeader.options); // display as string ?
ctrl.msg ("");
ctrl.msg ("extensions:");
ctrl.msg (" author: %s", m_extenHeader.author);
ctrl.msg (" modified_by: %s", m_extenHeader.modified);
ctrl.msg (" bsp_size: %d", m_extenHeader.mapSize);
}
void BotGraph::calculatePathRadius (int index) {
// calculate "wayzones" for the nearest node (meaning a dynamic distance area to vary node origin)
@ -1388,7 +1405,7 @@ void BotGraph::initNarrowPlaces () {
constexpr int32 kNarrowPlacesMinGraphVersion = 2;
// if version 2 or higher, narrow places already initialized and saved into file
if (m_version >= kNarrowPlacesMinGraphVersion) {
if (m_graphHeader.version >= kNarrowPlacesMinGraphVersion) {
m_narrowChecked = true;
return;
}
@ -1560,7 +1577,7 @@ bool BotGraph::convertOldFormat () {
if (!m_paths.empty ()) {
ctrl.msg ("Converting old PWF to new format Graph.");
m_tempStrings = header.author;
m_graphAuthor = header.author;
return saveGraphData ();
}
return true;
@ -1736,7 +1753,7 @@ template <typename U> bool BotGraph::loadStorage (StringRef ext, StringRef name,
// save graph version
if (isGraph) {
m_version = hdr.version;
memcpy (&m_graphHeader, &hdr, sizeof (StorageHeader));
}
// check the storage type
@ -1765,7 +1782,24 @@ template <typename U> bool BotGraph::loadStorage (StringRef ext, StringRef name,
// author of graph.. save
if ((hdr.options & StorageOption::Exten) && exten != nullptr) {
file.read (exten, sizeof (ExtenHeader));
size_t extenSize = sizeof (ExtenHeader);
if (hdr.version < 3) {
extenSize -= sizeof (char[32]); // modified by
}
file.read (exten, extenSize);
if (isGraph) {
strings.copy (m_extenHeader.author, exten->author, cr::bufsize (exten->author));
if (hdr.version > 2) {
strings.copy (m_extenHeader.modified, exten->modified, cr::bufsize (exten->modified));
}
else {
strings.copy (m_extenHeader.modified, "(none)", cr::bufsize (exten->modified));
}
m_extenHeader.mapSize = exten->mapSize;
}
}
ctrl.msg ("Successfully loaded Bots %s data v%d (%d/%.2fMB).", name, hdr.version, m_paths.length (), static_cast <float> (data.capacity () * sizeof (U)) / 1024.0f / 1024.0f);
file.close ();
@ -1782,6 +1816,9 @@ bool BotGraph::loadGraphData () {
ExtenHeader exten {};
int32 outOptions = 0;
m_graphHeader = {};
m_extenHeader = {};
// check if loaded
bool dataLoaded = loadStorage <Path> ("graph", "Graph", StorageOption::Graph, StorageVersion::Graph, m_paths, &exten, &outOptions);
@ -1795,11 +1832,16 @@ bool BotGraph::loadGraphData () {
}
if ((outOptions & StorageOption::Official) || strncmp (exten.author, "official", 8) == 0 || strlen (exten.author) < 2) {
m_tempStrings.assign (product.folder);
m_graphAuthor.assign (product.folder);
}
else {
m_tempStrings.assign (exten.author);
m_graphAuthor.assign (exten.author);
}
if (m_graphHeader.version > 2) {
m_graphModified.assign (exten.modified);
}
initNodesTypes ();
loadPathMatrix ();
loadVisibility ();
@ -1827,8 +1869,8 @@ bool BotGraph::saveGraphData () {
auto options = StorageOption::Graph | StorageOption::Exten;
String author;
if (game.isNullEntity (m_editor) && !m_tempStrings.empty ()) {
author = m_tempStrings;
if (game.isNullEntity (m_editor) && !m_graphAuthor.empty ()) {
author = m_graphAuthor;
if (!game.isDedicated ()) {
options |= StorageOption::Recovered;
@ -1847,7 +1889,16 @@ bool BotGraph::saveGraphData () {
}
ExtenHeader exten {};
strings.copy (exten.author, author.chars (), cr::bufsize (exten.author));
// only modify the author if no author currenlty assigned to graph file
if (m_graphAuthor.empty ()) {
strings.copy (exten.author, author.chars (), cr::bufsize (exten.author));
}
else {
strings.copy (exten.author, m_extenHeader.author, cr::bufsize (exten.author));
}
strings.copy (exten.modified, author.chars (), cr::bufsize (exten.author)); // always update modified by
exten.mapSize = getBspSize ();
// ensure narrow places saved into file
@ -2884,7 +2935,6 @@ BotGraph::BotGraph () {
m_rescuePoints.clear ();
m_sniperPoints.clear ();
m_version = StorageVersion::Graph;
m_loadAttempts = 0;
m_editFlags = 0;

View file

@ -294,10 +294,16 @@ void BotSupport::checkWelcome () {
game.serverCommand ("speak \"%s\"", m_sentences.random ());
}
String authorStr = "Official Navigation Graph";
StringRef graphAuthor = graph.getAuthor ();
StringRef graphModified = graph.getModifiedBy ();
if (!graphAuthor.startsWith (product.folder)) {
authorStr.assignf ("Navigation Graph by: %s", graphAuthor);
if (!graphModified.empty ()) {
authorStr.appendf (" (Modified by: %s)", graphModified);
}
}
MessageWriter (MSG_ONE, msgs.id (NetMsg::TextMsg), nullptr, receiveEntity)