graph: save narrow places to file, so, bump graph version.
graph: allow saving / loading graph manually on dedicated server. config: fix parsing for difficulty.cfg fixes #142 fix: restore fakeclient bit on entity flags every frame.
This commit is contained in:
parent
f51d3bf13b
commit
2d3078f851
8 changed files with 65 additions and 20 deletions
|
|
@ -20,7 +20,7 @@
|
||||||
CR_NAMESPACE_BEGIN
|
CR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
// see https://github.com/encode84/ulz/
|
// see https://github.com/encode84/ulz/
|
||||||
class ULZ final : DenyCopying {
|
class ULZ final : public Singleton <ULZ> {
|
||||||
public:
|
public:
|
||||||
enum : int32 {
|
enum : int32 {
|
||||||
Excess = 16,
|
Excess = 16,
|
||||||
|
|
@ -314,4 +314,7 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// expose global ulz object
|
||||||
|
CR_EXPOSE_GLOBAL_SINGLETON (ULZ, ulz);
|
||||||
|
|
||||||
CR_NAMESPACE_END
|
CR_NAMESPACE_END
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ CR_DECLARE_SCOPED_ENUM (StorageOption,
|
||||||
|
|
||||||
// storage header versions
|
// storage header versions
|
||||||
CR_DECLARE_SCOPED_ENUM (StorageVersion,
|
CR_DECLARE_SCOPED_ENUM (StorageVersion,
|
||||||
Graph = 1,
|
Graph = 2,
|
||||||
Practice = 1,
|
Practice = 1,
|
||||||
Vistable = 1,
|
Vistable = 1,
|
||||||
Matrix = 1,
|
Matrix = 1,
|
||||||
|
|
@ -251,6 +251,7 @@ private:
|
||||||
int x, y, z;
|
int x, y, z;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int m_version;
|
||||||
int m_editFlags;
|
int m_editFlags;
|
||||||
int m_loadAttempts;
|
int m_loadAttempts;
|
||||||
int m_cacheNodeIndex;
|
int m_cacheNodeIndex;
|
||||||
|
|
@ -325,6 +326,7 @@ public:
|
||||||
|
|
||||||
bool saveGraphData ();
|
bool saveGraphData ();
|
||||||
bool loadGraphData ();
|
bool loadGraphData ();
|
||||||
|
bool canDownload ();
|
||||||
|
|
||||||
template <typename U> bool saveStorage (StringRef ext, StringRef name, StorageOption options, StorageVersion version, const SmallArray <U> &data, ExtenHeader *exten);
|
template <typename U> bool saveStorage (StringRef ext, StringRef name, StorageOption options, StorageVersion version, const SmallArray <U> &data, ExtenHeader *exten);
|
||||||
template <typename U> bool loadStorage (StringRef ext, StringRef name, StorageOption options, StorageVersion version, SmallArray <U> &data, ExtenHeader *exten, int32 *outOptions);
|
template <typename U> bool loadStorage (StringRef ext, StringRef name, StorageOption options, StorageVersion version, SmallArray <U> &data, ExtenHeader *exten, int32 *outOptions);
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ cdata.set ('commitCount', run_command ('git', 'rev-list', '--count', 'HEAD').std
|
||||||
cdata.set ('commitAuthor', run_command ('git', 'log', '--pretty="%ae"', '-1').stdout ().strip ())
|
cdata.set ('commitAuthor', run_command ('git', 'log', '--pretty="%ae"', '-1').stdout ().strip ())
|
||||||
|
|
||||||
cdata.set ('buildVersion', buildVersion)
|
cdata.set ('buildVersion', buildVersion)
|
||||||
cdata.set ('buildMachine', run_command ('hostname').stdout ().strip ())
|
cdata.set ('buildMachine', run_command ('hostname', '-f').stdout ().strip ())
|
||||||
cdata.set ('buildCompiler', compilerId + ' ' + compilerVersion)
|
cdata.set ('buildCompiler', compilerId + ' ' + compilerVersion)
|
||||||
|
|
||||||
configure_file (input: 'inc/version.h.in', output: 'version.build.h', configuration: cdata)
|
configure_file (input: 'inc/version.h.in', output: 'version.build.h', configuration: cdata)
|
||||||
|
|
|
||||||
|
|
@ -2940,6 +2940,8 @@ void Bot::frame () {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bot::update () {
|
void Bot::update () {
|
||||||
|
pev->flags |= FL_FAKECLIENT; // restore fake client bit
|
||||||
|
|
||||||
pev->button = 0;
|
pev->button = 0;
|
||||||
|
|
||||||
m_moveSpeed = 0.0f;
|
m_moveSpeed = 0.0f;
|
||||||
|
|
|
||||||
|
|
@ -586,7 +586,7 @@ void BotConfig::loadDifficultyConfig () {
|
||||||
if (util.openConfig ("difficulty.cfg", "Difficulty config file not found. Loading defaults.", &file)) {
|
if (util.openConfig ("difficulty.cfg", "Difficulty config file not found. Loading defaults.", &file)) {
|
||||||
|
|
||||||
while (file.getLine (line)) {
|
while (file.getLine (line)) {
|
||||||
if (isCommentLine (line)) {
|
if (isCommentLine (line) || line.length () < 3) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto items = line.split ("=");
|
auto items = line.split ("=");
|
||||||
|
|
|
||||||
|
|
@ -269,8 +269,25 @@ int BotControl::cmdCvars () {
|
||||||
int BotControl::cmdNode () {
|
int BotControl::cmdNode () {
|
||||||
enum args { root, alias, cmd, cmd2 };
|
enum args { root, alias, cmd, cmd2 };
|
||||||
|
|
||||||
|
static Array <StringRef> allowedOnDedicatedServer {
|
||||||
|
"acquire_editor",
|
||||||
|
"upload",
|
||||||
|
"save",
|
||||||
|
"load"
|
||||||
|
};
|
||||||
|
|
||||||
|
// check if cmd is allowed on dedicated server
|
||||||
|
auto isAllowedOnDedicatedServer = [] (StringRef str) -> bool {
|
||||||
|
for (const auto &test : allowedOnDedicatedServer) {
|
||||||
|
if (test == str) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
// graph editor supported only with editor
|
// graph editor supported only with editor
|
||||||
if (game.isDedicated () && !graph.hasEditor () && strValue (cmd) != "acquire_editor" && strValue (cmd) != "upload") {
|
if (game.isDedicated () && !graph.hasEditor () && !isAllowedOnDedicatedServer (strValue (cmd))) {
|
||||||
msg ("Unable to use graph edit commands without setting graph editor player. Please use \"graph acquire_editor\" to acquire rights for graph editing.");
|
msg ("Unable to use graph edit commands without setting graph editor player. Please use \"graph acquire_editor\" to acquire rights for graph editing.");
|
||||||
return BotCommandResult::Handled;
|
return BotCommandResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
@ -738,7 +755,7 @@ int BotControl::cmdNodeUpload () {
|
||||||
http.setTimeout (6);
|
http.setTimeout (6);
|
||||||
|
|
||||||
// try to upload the file
|
// try to upload the file
|
||||||
if (http.uploadFile ("http://yapb.ru/graph", strings.format ("%sgraph/%s.graph", graph.getDataDirectory (false), game.getMapName ()))) {
|
if (http.uploadFile (strings.format ("http://%s/graph", product.download), strings.format ("%sgraph/%s.graph", graph.getDataDirectory (false), game.getMapName ()))) {
|
||||||
msg ("Graph file was successfully validated and uploaded to the YaPB Graph DB (%s).", product.download);
|
msg ("Graph file was successfully validated and uploaded to the YaPB Graph DB (%s).", product.download);
|
||||||
msg ("It will be available for download for all YaPB users in a few minutes.");
|
msg ("It will be available for download for all YaPB users in a few minutes.");
|
||||||
msg ("\n");
|
msg ("\n");
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
#include <yapb.h>
|
#include <yapb.h>
|
||||||
|
|
||||||
ConVar cv_graph_fixcamp ("yb_graph_fixcamp", "1", "Specifies whether bot should not 'fix' camp directions of camp waypoints when loading old PWF format.");
|
ConVar cv_graph_fixcamp ("yb_graph_fixcamp", "1", "Specifies whether bot should not 'fix' camp directions of camp waypoints when loading old PWF format.");
|
||||||
ConVar cv_graph_url ("yb_graph_url", product.download.chars (), "Specifies the URL from bots will be able to download graph in case of missing local one.", false, 0.0f, 0.0f);
|
ConVar cv_graph_url ("yb_graph_url", product.download.chars (), "Specifies the URL from bots will be able to download graph in case of missing local one. Set to empty, if no downloads needed.", false, 0.0f, 0.0f);
|
||||||
|
|
||||||
void BotGraph::initGraph () {
|
void BotGraph::initGraph () {
|
||||||
// this function initialize the graph structures..
|
// this function initialize the graph structures..
|
||||||
|
|
@ -1316,6 +1316,13 @@ void BotGraph::initNarrowPlaces () {
|
||||||
if (m_paths.empty () || m_narrowChecked) {
|
if (m_paths.empty () || m_narrowChecked) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
constexpr int32 kNarrowPlacesMinGraphVersion = 2;
|
||||||
|
|
||||||
|
// if version 2 or higher, narrow places already initialized and saved into file
|
||||||
|
if (m_version >= kNarrowPlacesMinGraphVersion) {
|
||||||
|
m_narrowChecked = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
TraceResult tr;
|
TraceResult tr;
|
||||||
|
|
||||||
const auto distance = 178.0f;
|
const auto distance = 178.0f;
|
||||||
|
|
@ -1518,13 +1525,11 @@ template <typename U> bool BotGraph::saveStorage (StringRef ext, StringRef name,
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ULZ lz;
|
|
||||||
|
|
||||||
int32 rawLength = data.template length <int32> () * sizeof (U);
|
int32 rawLength = data.template length <int32> () * sizeof (U);
|
||||||
SmallArray <uint8> compressed (rawLength + sizeof (uint8) * ULZ::Excess);
|
SmallArray <uint8> compressed (rawLength + sizeof (uint8) * ULZ::Excess);
|
||||||
|
|
||||||
// try to compress
|
// try to compress
|
||||||
auto compressedLength = lz.compress (reinterpret_cast <uint8 *> (data.data ()), rawLength, reinterpret_cast <uint8 *> (compressed.data ()));
|
auto compressedLength = ulz.compress (reinterpret_cast <uint8 *> (data.data ()), rawLength, reinterpret_cast <uint8 *> (compressed.data ()));
|
||||||
|
|
||||||
if (compressedLength > 0) {
|
if (compressedLength > 0) {
|
||||||
StorageHeader hdr {};
|
StorageHeader hdr {};
|
||||||
|
|
@ -1585,11 +1590,11 @@ template <typename U> bool BotGraph::loadStorage (StringRef ext, StringRef name,
|
||||||
|
|
||||||
// downloader for graph
|
// downloader for graph
|
||||||
auto download = [&] () -> bool {
|
auto download = [&] () -> bool {
|
||||||
auto downloadAddress = cv_graph_url.str ();
|
if (!graph.canDownload ()) {
|
||||||
|
|
||||||
if (strings.isEmpty (downloadAddress)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
auto downloadAddress = cv_graph_url.str ();
|
||||||
|
|
||||||
auto toDownload = strings.format ("%sgraph/%s", getDataDirectory (false), filename);
|
auto toDownload = strings.format ("%sgraph/%s", getDataDirectory (false), filename);
|
||||||
auto fromDownload = strings.format ("http://%s/graph/%s", downloadAddress, filename);
|
auto fromDownload = strings.format ("http://%s/graph/%s", downloadAddress, filename);
|
||||||
|
|
||||||
|
|
@ -1599,7 +1604,7 @@ template <typename U> bool BotGraph::loadStorage (StringRef ext, StringRef name,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
game.print ("Can't download '%s'. from '%s' to '%s'... (%d).", filename, fromDownload, toDownload, http.getLastStatusCode ());
|
game.print ("Can't download '%s' from '%s' to '%s'... (%d).", filename, fromDownload, toDownload, http.getLastStatusCode ());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
@ -1656,13 +1661,18 @@ template <typename U> bool BotGraph::loadStorage (StringRef ext, StringRef name,
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the version
|
// check the version
|
||||||
if (hdr.version != version) {
|
if (hdr.version > version) {
|
||||||
if (tryReload ()) {
|
if (tryReload ()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return raiseLoadingError (isGraph, file, "Damaged %s (filename: '%s'). Version number differs (got: '%d', need: '%d').", name, filename, hdr.version, version);
|
return raiseLoadingError (isGraph, file, "Damaged %s (filename: '%s'). Version number differs (got: '%d', need: '%d').", name, filename, hdr.version, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save graph version
|
||||||
|
if (isGraph) {
|
||||||
|
m_version = hdr.version;
|
||||||
|
}
|
||||||
|
|
||||||
// check the storage type
|
// check the storage type
|
||||||
if ((hdr.options & options) != options) {
|
if ((hdr.options & options) != options) {
|
||||||
return raiseLoadingError (isGraph, file, "Incorrect storage format for %s (filename: '%s').", name, filename);
|
return raiseLoadingError (isGraph, file, "Incorrect storage format for %s (filename: '%s').", name, filename);
|
||||||
|
|
@ -1676,10 +1686,9 @@ template <typename U> bool BotGraph::loadStorage (StringRef ext, StringRef name,
|
||||||
|
|
||||||
// read compressed data
|
// read compressed data
|
||||||
if (file.read (compressed.data (), sizeof (uint8), hdr.compressed) == static_cast <size_t> (hdr.compressed)) {
|
if (file.read (compressed.data (), sizeof (uint8), hdr.compressed) == static_cast <size_t> (hdr.compressed)) {
|
||||||
ULZ lz;
|
|
||||||
|
|
||||||
// try to uncompress
|
// try to uncompress
|
||||||
if (lz.uncompress (compressed.data (), hdr.compressed, reinterpret_cast <uint8 *> (data.data ()), hdr.uncompressed) == ULZ::UncompressFailure) {
|
if (ulz.uncompress (compressed.data (), hdr.compressed, reinterpret_cast <uint8 *> (data.data ()), hdr.uncompressed) == ULZ::UncompressFailure) {
|
||||||
return raiseLoadingError (isGraph, file, "Unable to decompress ULZ data for %s (filename: '%s').", name, filename);
|
return raiseLoadingError (isGraph, file, "Unable to decompress ULZ data for %s (filename: '%s').", name, filename);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -1692,7 +1701,7 @@ template <typename U> bool BotGraph::loadStorage (StringRef ext, StringRef name,
|
||||||
if ((hdr.options & StorageOption::Exten) && exten != nullptr) {
|
if ((hdr.options & StorageOption::Exten) && exten != nullptr) {
|
||||||
file.read (exten, sizeof (ExtenHeader));
|
file.read (exten, sizeof (ExtenHeader));
|
||||||
}
|
}
|
||||||
game.print ("Successfully loaded Bots %s data (%d/%.2fMB).", name, m_paths.length (), static_cast <float> (data.capacity () * sizeof (U)) / 1024.0f / 1024.0f);
|
game.print ("Successfully loaded Bots %s data v%d.0 (%d/%.2fMB).", name, hdr.version, m_paths.length (), static_cast <float> (data.capacity () * sizeof (U)) / 1024.0f / 1024.0f);
|
||||||
file.close ();
|
file.close ();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1747,6 +1756,10 @@ bool BotGraph::loadGraphData () {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BotGraph::canDownload () {
|
||||||
|
return !strings.isEmpty (cv_graph_url.str ());
|
||||||
|
}
|
||||||
|
|
||||||
bool BotGraph::saveGraphData () {
|
bool BotGraph::saveGraphData () {
|
||||||
auto options = StorageOption::Graph | StorageOption::Exten;
|
auto options = StorageOption::Graph | StorageOption::Exten;
|
||||||
String author;
|
String author;
|
||||||
|
|
@ -1754,8 +1767,10 @@ bool BotGraph::saveGraphData () {
|
||||||
if (game.isNullEntity (m_editor) && !m_tempStrings.empty ()) {
|
if (game.isNullEntity (m_editor) && !m_tempStrings.empty ()) {
|
||||||
author = m_tempStrings;
|
author = m_tempStrings;
|
||||||
|
|
||||||
|
if (!game.isDedicated ()) {
|
||||||
options |= StorageOption::Recovered;
|
options |= StorageOption::Recovered;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (!game.isNullEntity (m_editor)) {
|
else if (!game.isNullEntity (m_editor)) {
|
||||||
author = m_editor->v.netname.chars ();
|
author = m_editor->v.netname.chars ();
|
||||||
}
|
}
|
||||||
|
|
@ -1772,6 +1787,10 @@ bool BotGraph::saveGraphData () {
|
||||||
strings.copy (exten.author, author.chars (), cr::bufsize (exten.author));
|
strings.copy (exten.author, author.chars (), cr::bufsize (exten.author));
|
||||||
exten.mapSize = engfuncs.pfnGetFileSize (strings.format ("maps/%s.bsp", game.getMapName ()));
|
exten.mapSize = engfuncs.pfnGetFileSize (strings.format ("maps/%s.bsp", game.getMapName ()));
|
||||||
|
|
||||||
|
// ensure narrow places saved into file
|
||||||
|
m_narrowChecked = false;
|
||||||
|
initNarrowPlaces ();
|
||||||
|
|
||||||
return saveStorage <Path> ("graph", "Graph", static_cast <StorageOption> (options), StorageVersion::Graph, m_paths, &exten);
|
return saveStorage <Path> ("graph", "Graph", static_cast <StorageOption> (options), StorageVersion::Graph, m_paths, &exten);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2798,8 +2817,10 @@ BotGraph::BotGraph () {
|
||||||
m_rescuePoints.clear ();
|
m_rescuePoints.clear ();
|
||||||
m_sniperPoints.clear ();
|
m_sniperPoints.clear ();
|
||||||
|
|
||||||
|
m_version = StorageVersion::Graph;
|
||||||
m_loadAttempts = 0;
|
m_loadAttempts = 0;
|
||||||
m_editFlags = 0;
|
m_editFlags = 0;
|
||||||
|
|
||||||
m_pathDisplayTime = 0.0f;
|
m_pathDisplayTime = 0.0f;
|
||||||
m_arrowDisplayTime = 0.0f;
|
m_arrowDisplayTime = 0.0f;
|
||||||
m_autoPathDistance = 250.0f;
|
m_autoPathDistance = 250.0f;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue