Custom.cfg (#213)
Added custom configs. These are used for replacing some hardcoded strings inside bot code, currently custom cvar for parachute detection is available, as well as custom c4 model names. Added editorconfig, and fixed CRLF for files (was a mix between LF & CRLF). Fixed use-after-free sanitizer error with chatlib. Fixed configs files loaded with memory-loader does not process last line in config files.
This commit is contained in:
parent
ed46e3238d
commit
075bff2988
21 changed files with 533 additions and 404 deletions
10
.editorconfig
Normal file
10
.editorconfig
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
# http://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 3
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
22
cfg/addons/yapb/conf/custom.cfg
Normal file
22
cfg/addons/yapb/conf/custom.cfg
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
;
|
||||||
|
; @package: YaPB
|
||||||
|
; @version: 4.2
|
||||||
|
; @author: YaPB Development Team
|
||||||
|
; @filename: yapb.cfg
|
||||||
|
;
|
||||||
|
; Custom configuration file, allow to change some hardcoded stuff in bot code.
|
||||||
|
;
|
||||||
|
|
||||||
|
;
|
||||||
|
; Custom name for C4 model, for servers that replacing C4 model with it's own.
|
||||||
|
; By default it's "c4.mdl" (the models/ path is omitted), so if you need to use
|
||||||
|
; "models/mybomb/mybomb.mdl", you should specify "mybomb/mybomb.mdl".
|
||||||
|
;
|
||||||
|
C4ModelName = c4.mdl
|
||||||
|
|
||||||
|
;
|
||||||
|
; Custon cvar name for parachute handling, there are all the different plugins that
|
||||||
|
; handles parachute (AMX Parachute, AMX Parachute Lite, etc..), you can specify needed
|
||||||
|
; cvar here.
|
||||||
|
;
|
||||||
|
AMXParachuteCvar = sv_parachute
|
||||||
|
|
@ -1994,9 +1994,3 @@ You're launched standalone version of %s. Metamod is not installed or not enable
|
||||||
|
|
||||||
[TRANSLATED]
|
[TRANSLATED]
|
||||||
Вы запустили автономную версию %s. Metamod не установлен или не включён!
|
Вы запустили автономную версию %s. Metamod не установлен или не включён!
|
||||||
|
|
||||||
[ORIGINAL]
|
|
||||||
EndOfFile
|
|
||||||
|
|
||||||
[TRANSLATED]
|
|
||||||
EndOfFile
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//
|
//
|
||||||
// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge.
|
// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge.
|
||||||
// Copyright © 2004-2020 YaPB Project <yapb@jeefo.net>.
|
// Copyright © 2004-2020 YaPB Project <yapb@jeefo.net>.
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,8 @@ public:
|
||||||
int ch = 0;
|
int ch = 0;
|
||||||
SmallArray <char> data (255);
|
SmallArray <char> data (255);
|
||||||
|
|
||||||
|
line.clear ();
|
||||||
|
|
||||||
while ((ch = get ()) != EOF && !eof ()) {
|
while ((ch = get ()) != EOF && !eof ()) {
|
||||||
data.push (static_cast <char> (ch));
|
data.push (static_cast <char> (ch));
|
||||||
|
|
||||||
|
|
@ -78,9 +80,10 @@ public:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
line.assign (data.data (), data.length ());
|
if (!data.empty ()) {
|
||||||
|
line.assign (data.data (), data.length ());
|
||||||
return !eof ();
|
}
|
||||||
|
return !line.empty ();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ...Args> size_t puts (const char *fmt, Args &&...args) {
|
template <typename ...Args> size_t puts (const char *fmt, Args &&...args) {
|
||||||
|
|
@ -282,10 +285,7 @@ public:
|
||||||
if (!contents_ || seek_ >= length_) {
|
if (!contents_ || seek_ >= length_) {
|
||||||
return Eof;
|
return Eof;
|
||||||
}
|
}
|
||||||
auto ch = contents_[seek_];
|
return static_cast <char> (contents_[seek_++]);
|
||||||
++seek_;
|
|
||||||
|
|
||||||
return static_cast <char> (ch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *getString (char *buffer, size_t count) {
|
char *getString (char *buffer, size_t count) {
|
||||||
|
|
@ -315,16 +315,20 @@ public:
|
||||||
char ch;
|
char ch;
|
||||||
SmallArray <char> data (255);
|
SmallArray <char> data (255);
|
||||||
|
|
||||||
while ((ch = get ()) != Eof) {
|
line.clear ();
|
||||||
|
|
||||||
|
while ((ch = get ()) != Eof && !eof ()) {
|
||||||
data.push (ch);
|
data.push (ch);
|
||||||
|
|
||||||
if (ch == '\n') {
|
if (ch == '\n') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
line.assign (data.data (), data.length ());
|
|
||||||
|
|
||||||
return !eof ();
|
if (!data.empty ()) {
|
||||||
|
line.assign (data.data (), data.length ());
|
||||||
|
}
|
||||||
|
return !line.empty ();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t read (void *buffer, size_t size, size_t count = 1) {
|
size_t read (void *buffer, size_t size, size_t count = 1) {
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,6 @@ CR_DECLARE_SCOPED_ENUM (HttpClientResult,
|
||||||
|
|
||||||
CR_NAMESPACE_BEGIN
|
CR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
// simple http uri omitting query-string and port
|
// simple http uri omitting query-string and port
|
||||||
|
|
@ -281,12 +280,10 @@ private:
|
||||||
String userAgent_ = "crlib";
|
String userAgent_ = "crlib";
|
||||||
HttpClientResult statusCode_ = HttpClientResult::Undefined;
|
HttpClientResult statusCode_ = HttpClientResult::Undefined;
|
||||||
int32 chunkSize_ = 4096;
|
int32 chunkSize_ = 4096;
|
||||||
|
bool initialized_ = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HttpClient () {
|
HttpClient () = default;
|
||||||
detail::SocketInit::start ();
|
|
||||||
}
|
|
||||||
|
|
||||||
~HttpClient () = default;
|
~HttpClient () = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -333,9 +330,17 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void startup () {
|
||||||
|
detail::SocketInit::start ();
|
||||||
|
initialized_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
// simple blocked download
|
// simple blocked download
|
||||||
bool downloadFile (StringRef url, StringRef localPath, int32 timeout = DefaultSocketTimeout) {
|
bool downloadFile (StringRef url, StringRef localPath, int32 timeout = DefaultSocketTimeout) {
|
||||||
|
if (plat.win && !initialized_) {
|
||||||
|
plat.abort ("Sockets not initialized.");
|
||||||
|
}
|
||||||
|
|
||||||
if (File::exists (localPath)) {
|
if (File::exists (localPath)) {
|
||||||
statusCode_ = HttpClientResult::LocalFileExists;
|
statusCode_ = HttpClientResult::LocalFileExists;
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -402,6 +407,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool uploadFile (StringRef url, StringRef localPath, const int32 timeout = DefaultSocketTimeout) {
|
bool uploadFile (StringRef url, StringRef localPath, const int32 timeout = DefaultSocketTimeout) {
|
||||||
|
if (plat.win && !initialized_) {
|
||||||
|
plat.abort ("Sockets not initialized.");
|
||||||
|
}
|
||||||
|
|
||||||
if (!File::exists (localPath)) {
|
if (!File::exists (localPath)) {
|
||||||
statusCode_ = HttpClientResult::NoLocalFile;
|
statusCode_ = HttpClientResult::NoLocalFile;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
22
inc/config.h
22
inc/config.h
|
|
@ -51,6 +51,7 @@ private:
|
||||||
|
|
||||||
HashMap <uint32, String, Hash <int32>> m_language;
|
HashMap <uint32, String, Hash <int32>> m_language;
|
||||||
HashMap <int32, DifficultyData> m_difficulty;
|
HashMap <int32, DifficultyData> m_difficulty;
|
||||||
|
HashMap <String, String> m_custom;
|
||||||
|
|
||||||
// default tables for personality weapon preferences, overridden by weapon.cfg
|
// default tables for personality weapon preferences, overridden by weapon.cfg
|
||||||
SmallArray <int32> m_normalWeaponPrefs = { 0, 2, 1, 4, 5, 6, 3, 12, 10, 24, 25, 13, 11, 8, 7, 22, 23, 18, 21, 17, 19, 15, 17, 9, 14, 16 };
|
SmallArray <int32> m_normalWeaponPrefs = { 0, 2, 1, 4, 5, 6, 3, 12, 10, 24, 25, 13, 11, 8, 7, 22, 23, 18, 21, 17, 19, 15, 17, 9, 14, 16 };
|
||||||
|
|
@ -98,6 +99,9 @@ public:
|
||||||
// loads bots map-specific config
|
// loads bots map-specific config
|
||||||
void loadMapSpecificConfig ();
|
void loadMapSpecificConfig ();
|
||||||
|
|
||||||
|
// loads custom config
|
||||||
|
void loadCustomConfig ();
|
||||||
|
|
||||||
// sets memfile to use engine functions
|
// sets memfile to use engine functions
|
||||||
void setupMemoryFiles ();
|
void setupMemoryFiles ();
|
||||||
|
|
||||||
|
|
@ -119,6 +123,9 @@ public:
|
||||||
// translates bot message into needed language
|
// translates bot message into needed language
|
||||||
const char *translate (StringRef input);
|
const char *translate (StringRef input);
|
||||||
|
|
||||||
|
// display current custom values
|
||||||
|
void showCustomValues ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isCommentLine (StringRef line) const {
|
bool isCommentLine (StringRef line) const {
|
||||||
if (line.empty ()) {
|
if (line.empty ()) {
|
||||||
|
|
@ -237,6 +244,21 @@ public:
|
||||||
StringRef getRandomLogoName (int index) {
|
StringRef getRandomLogoName (int index) {
|
||||||
return m_logos[index];
|
return m_logos[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get custom value
|
||||||
|
StringRef fetchCustom (StringRef name) {
|
||||||
|
if (m_custom.has (name)) {
|
||||||
|
return m_custom[name];
|
||||||
|
}
|
||||||
|
SimpleLogger::instance ().error ("Trying to fetch uknonwn custom variable: %s", name);
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// simple accessor to c4 model name
|
||||||
|
StringRef getBombModelName () {
|
||||||
|
return fetchCustom ("C4ModelName");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// explose global
|
// explose global
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,7 @@ private:
|
||||||
int cmdMenu ();
|
int cmdMenu ();
|
||||||
int cmdList ();
|
int cmdList ();
|
||||||
int cmdCvars ();
|
int cmdCvars ();
|
||||||
|
int cmdShowCustom ();
|
||||||
int cmdNode ();
|
int cmdNode ();
|
||||||
int cmdNodeOn ();
|
int cmdNodeOn ();
|
||||||
int cmdNodeOff ();
|
int cmdNodeOff ();
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,10 @@ public:
|
||||||
|
|
||||||
// check if object inside frustum plane
|
// check if object inside frustum plane
|
||||||
bool isObjectInsidePlane (FrustumPlane &plane, const Vector ¢er, float height, float radius);
|
bool isObjectInsidePlane (FrustumPlane &plane, const Vector ¢er, float height, float radius);
|
||||||
|
|
||||||
|
// checks if same model ommiting the models directory
|
||||||
|
bool isModel (const edict_t *ent, StringRef model);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// re-show welcome after changelevel ?
|
// re-show welcome after changelevel ?
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,6 @@
|
||||||
#define MODULE_BUILD_MACHINE "localhost"
|
#define MODULE_BUILD_MACHINE "localhost"
|
||||||
#define MODULE_BUILD_COMPILER "unknown"
|
#define MODULE_BUILD_COMPILER "unknown"
|
||||||
|
|
||||||
#define MODULE_BOT_VERSION "4.1"
|
#define MODULE_BOT_VERSION "4.2"
|
||||||
#define MODULE_BOT_VERSION_FILE 4,0,0,000
|
#define MODULE_BOT_VERSION_FILE 4,2,0,000
|
||||||
#define MODULE_BOT_BUILD_ID "0:0"
|
#define MODULE_BOT_BUILD_ID "0:0"
|
||||||
|
|
|
||||||
333
meson.build
333
meson.build
|
|
@ -6,25 +6,25 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
project (
|
project (
|
||||||
'yapb',
|
'yapb',
|
||||||
'cpp',
|
'cpp',
|
||||||
|
|
||||||
version: '4.1',
|
version: '4.2',
|
||||||
license: 'MIT',
|
license: 'MIT',
|
||||||
|
|
||||||
default_options: [
|
default_options: [
|
||||||
'buildtype=release',
|
'buildtype=release',
|
||||||
'b_ndebug=if-release',
|
'b_ndebug=if-release',
|
||||||
'cpp_std=c++14',
|
'cpp_std=c++14',
|
||||||
'warning_level=3',
|
'warning_level=3',
|
||||||
'werror=true',
|
'werror=true',
|
||||||
'backend=ninja',
|
'backend=ninja',
|
||||||
'strip=true',
|
'strip=true',
|
||||||
'optimization=3',
|
'optimization=3',
|
||||||
'default_library=static',
|
'default_library=static',
|
||||||
'cpp_eh=none'
|
'cpp_eh=none'
|
||||||
],
|
],
|
||||||
meson_version: '>=0.48.0')
|
meson_version: '>=0.48.0')
|
||||||
|
|
||||||
find_program ('ninja', required: true)
|
find_program ('ninja', required: true)
|
||||||
find_program ('git', required: true)
|
find_program ('git', required: true)
|
||||||
|
|
@ -53,9 +53,9 @@ ccflags = []
|
||||||
cdata = configuration_data()
|
cdata = configuration_data()
|
||||||
|
|
||||||
if isWindows
|
if isWindows
|
||||||
cdata.set ('buildVersionWin', ','.join (buildVersion.split ('.')))
|
cdata.set ('buildVersionWin', ','.join (buildVersion.split ('.')))
|
||||||
else
|
else
|
||||||
cdata.set ('buildVersionWin', buildVersion)
|
cdata.set ('buildVersionWin', buildVersion)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
cdata.set ('commitHash', run_command ('git', 'rev-parse', '--short', 'HEAD').stdout ().strip ())
|
cdata.set ('commitHash', run_command ('git', 'rev-parse', '--short', 'HEAD').stdout ().strip ())
|
||||||
|
|
@ -71,199 +71,198 @@ configure_file (input: 'inc/version.h.in', output: 'version.build.h', configurat
|
||||||
ccflags += '-DVERSION_GENERATED'
|
ccflags += '-DVERSION_GENERATED'
|
||||||
|
|
||||||
if isCLang or isGCC or (isIntel and not isWindows)
|
if isCLang or isGCC or (isIntel and not isWindows)
|
||||||
ccflags += [
|
ccflags += [
|
||||||
'-m32',
|
'-m32',
|
||||||
'-fno-threadsafe-statics',
|
'-fno-threadsafe-statics',
|
||||||
'-fno-exceptions',
|
'-fno-exceptions',
|
||||||
'-fno-rtti'
|
'-fno-rtti'
|
||||||
]
|
]
|
||||||
|
|
||||||
if not isDarwin
|
if not isDarwin
|
||||||
ccflags += [
|
ccflags += [
|
||||||
'-pedantic',
|
'-pedantic',
|
||||||
]
|
]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if isOptimize
|
if isOptimize
|
||||||
ccflags += '-msse3'
|
ccflags += '-msse3'
|
||||||
|
|
||||||
if (isCLang or isGCC) and not isDarwin
|
if (isCLang or isGCC) and not isDarwin
|
||||||
ccflags += [
|
ccflags += [
|
||||||
'-flto',
|
'-flto',
|
||||||
'-fdata-sections',
|
'-fdata-sections',
|
||||||
'-ffunction-sections'
|
'-ffunction-sections'
|
||||||
]
|
]
|
||||||
|
|
||||||
if isGCC
|
if isGCC
|
||||||
ccflags += '-fgraphite-identity'
|
ccflags += '-fgraphite-identity'
|
||||||
ldflags += '-flto-partition=none'
|
ldflags += '-flto-partition=none'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ldflags += [
|
ldflags += [
|
||||||
'-flto',
|
'-flto',
|
||||||
'-Wl,--version-script=../version_script.lds',
|
'-Wl,--version-script=../version_script.lds',
|
||||||
'-Wl,--gc-sections'
|
'-Wl,--gc-sections'
|
||||||
]
|
]
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if isLinux
|
if isLinux
|
||||||
ldflags += [
|
ldflags += [
|
||||||
'-m32',
|
'-m32',
|
||||||
'-lm',
|
'-lm',
|
||||||
'-ldl'
|
'-ldl'
|
||||||
]
|
]
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if isIntel and (isLinux or isDarwin)
|
if isIntel and (isLinux or isDarwin)
|
||||||
ldflags += [
|
ldflags += [
|
||||||
'-static-intel',
|
'-static-intel',
|
||||||
'-no-intel-extensions'
|
'-no-intel-extensions'
|
||||||
]
|
]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if isLinux or isDarwin
|
if isLinux or isDarwin
|
||||||
if isDarwin
|
if isDarwin
|
||||||
ccflags += '-mmacosx-version-min=10.9'
|
ccflags += '-mmacosx-version-min=10.9'
|
||||||
ldflags += [
|
ldflags += [
|
||||||
'-dynamiclib',
|
'-dynamiclib',
|
||||||
'-lstdc++',
|
'-lstdc++',
|
||||||
'-mmacosx-version-min=10.9'
|
'-mmacosx-version-min=10.9'
|
||||||
]
|
]
|
||||||
else
|
else
|
||||||
ldflags += '-static-libgcc'
|
ldflags += '-static-libgcc'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if not isOptimize
|
if not isOptimize
|
||||||
ccflags += [
|
ccflags += [
|
||||||
'-g3',
|
'-g3',
|
||||||
'-ggdb',
|
'-ggdb',
|
||||||
'-DCR_DEBUG'
|
'-DCR_DEBUG'
|
||||||
]
|
]
|
||||||
else
|
else
|
||||||
ccflags += [
|
ccflags += [
|
||||||
'-mtune=generic',
|
'-mtune=generic',
|
||||||
'-msse3',
|
'-msse3',
|
||||||
'-mfpmath=sse',
|
'-mfpmath=sse',
|
||||||
'-fno-builtin',
|
'-fno-builtin',
|
||||||
'-funroll-loops',
|
'-funroll-loops',
|
||||||
'-fomit-frame-pointer',
|
'-fomit-frame-pointer',
|
||||||
'-fno-stack-protector',
|
'-fno-stack-protector',
|
||||||
'-fvisibility=hidden',
|
'-fvisibility=hidden',
|
||||||
'-fvisibility-inlines-hidden'
|
'-fvisibility-inlines-hidden'
|
||||||
]
|
]
|
||||||
|
|
||||||
if isIntel
|
if isIntel
|
||||||
ccflags += [
|
ccflags += [
|
||||||
'-ipo',
|
'-ipo',
|
||||||
'-wd11076',
|
'-wd11076',
|
||||||
'-wd11074'
|
'-wd11074'
|
||||||
]
|
]
|
||||||
|
|
||||||
ldflags += [
|
ldflags += [
|
||||||
'-cxxlib-nostd',
|
'-cxxlib-nostd',
|
||||||
'-Wl,--no-undefined,-z,notext,--gc-sections',
|
'-Wl,--no-undefined,-z,notext,--gc-sections',
|
||||||
'-ipo'
|
'-ipo'
|
||||||
]
|
]
|
||||||
elif isCLang and not isDarwin
|
elif isCLang and not isDarwin
|
||||||
llvmLinker = find_program ('lld', required: false)
|
llvmLinker = find_program ('lld', required: false)
|
||||||
|
|
||||||
if llvmLinker.found() == true
|
if llvmLinker.found() == true
|
||||||
ldflags += '-fuse-ld=' + llvmLinker.path ().split ('/')[-1]
|
ldflags += '-fuse-ld=' + llvmLinker.path ().split ('/')[-1]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ldflags += [
|
ldflags += [
|
||||||
'-nostdlib++',
|
'-nostdlib++',
|
||||||
'-Wunused-command-line-argument',
|
'-Wunused-command-line-argument',
|
||||||
'-Wl,-z,notext',
|
'-Wl,-z,notext',
|
||||||
'--no-undefined'
|
'--no-undefined'
|
||||||
]
|
]
|
||||||
elif isGCC and not isDarwin
|
elif isGCC and not isDarwin
|
||||||
ldflags += '-Wl,--no-undefined'
|
ldflags += '-Wl,--no-undefined'
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if isWindows and (isVC or isIntel)
|
if isWindows and (isVC or isIntel)
|
||||||
ldflags += [
|
ldflags += [
|
||||||
'/MACHINE:X86',
|
'/MACHINE:X86',
|
||||||
'user32.lib',
|
'user32.lib',
|
||||||
'ws2_32.lib'
|
'ws2_32.lib'
|
||||||
]
|
]
|
||||||
|
|
||||||
ccflags += [
|
ccflags += [
|
||||||
'/TP'
|
'/TP'
|
||||||
]
|
]
|
||||||
|
|
||||||
if isOptimize
|
if isOptimize
|
||||||
ccflags += [
|
ccflags += [
|
||||||
'/GL',
|
'/GL',
|
||||||
'/arch:SSE2',
|
'/arch:SSE2',
|
||||||
'/GS-',
|
'/GS-',
|
||||||
'/Ob2',
|
'/Ob2',
|
||||||
'/Oy',
|
'/Oy',
|
||||||
'/Oi'
|
'/Oi'
|
||||||
]
|
]
|
||||||
|
ldflags += '/LTCG'
|
||||||
ldflags += '/LTCG'
|
endif
|
||||||
endif
|
|
||||||
|
|
||||||
elif isWindows and (isCLang or isGCC)
|
elif isWindows and (isCLang or isGCC)
|
||||||
if isCLang
|
if isCLang
|
||||||
ldflags += '-Wl,/MACHINE:X86'
|
ldflags += '-Wl,/MACHINE:X86'
|
||||||
else
|
else
|
||||||
ldflags += [
|
ldflags += [
|
||||||
'-static-libgcc',
|
'-static-libgcc',
|
||||||
'-Wl,--kill-at'
|
'-Wl,--kill-at'
|
||||||
]
|
]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ldflags += [
|
ldflags += [
|
||||||
'-luser32',
|
'-luser32',
|
||||||
'-lws2_32'
|
'-lws2_32'
|
||||||
]
|
]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
add_global_arguments (ccflags, language: 'cpp')
|
add_global_arguments (ccflags, language: 'cpp')
|
||||||
add_global_link_arguments (ldflags, language: 'cpp')
|
add_global_link_arguments (ldflags, language: 'cpp')
|
||||||
|
|
||||||
sources = files (
|
sources = files (
|
||||||
'src/android.cpp',
|
'src/android.cpp',
|
||||||
'src/botlib.cpp',
|
'src/botlib.cpp',
|
||||||
'src/chatlib.cpp',
|
'src/chatlib.cpp',
|
||||||
'src/combat.cpp',
|
'src/combat.cpp',
|
||||||
'src/config.cpp',
|
'src/config.cpp',
|
||||||
'src/control.cpp',
|
'src/control.cpp',
|
||||||
'src/engine.cpp',
|
'src/engine.cpp',
|
||||||
'src/graph.cpp',
|
'src/graph.cpp',
|
||||||
'src/linkage.cpp',
|
'src/linkage.cpp',
|
||||||
'src/manager.cpp',
|
'src/manager.cpp',
|
||||||
'src/module.cpp',
|
'src/module.cpp',
|
||||||
'src/message.cpp',
|
'src/message.cpp',
|
||||||
'src/navigate.cpp',
|
'src/navigate.cpp',
|
||||||
'src/support.cpp'
|
'src/support.cpp'
|
||||||
)
|
)
|
||||||
|
|
||||||
includes = include_directories ([
|
includes = include_directories ([
|
||||||
'.', 'inc', 'ext',
|
'.', 'inc', 'ext',
|
||||||
], is_system: true)
|
], is_system: true)
|
||||||
|
|
||||||
if isWindows and not isCLang
|
if isWindows and not isCLang
|
||||||
sources += import('windows').compile_resources (
|
sources += import('windows').compile_resources (
|
||||||
'vc/yapb.rc',
|
'vc/yapb.rc',
|
||||||
include_directories: includes,
|
include_directories: includes,
|
||||||
args: ['-DVERSION_GENERATED']
|
args: ['-DVERSION_GENERATED']
|
||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
shared_library (
|
shared_library (
|
||||||
meson.project_name (),
|
meson.project_name (),
|
||||||
sources,
|
sources,
|
||||||
include_directories: includes,
|
include_directories: includes,
|
||||||
|
|
||||||
gnu_symbol_visibility: 'hidden',
|
gnu_symbol_visibility: 'hidden',
|
||||||
name_prefix: '')
|
name_prefix: '')
|
||||||
|
|
||||||
run_target ('package',
|
run_target ('package',
|
||||||
command : ['python', meson.source_root() + '/package.py', '@0@.@1@'.format (buildVersion, buildCount)])
|
command : ['python', meson.source_root() + '/package.py', '@0@.@1@'.format (buildVersion, buildCount)])
|
||||||
395
package.py
395
package.py
|
|
@ -1,4 +1,5 @@
|
||||||
#
|
# -*- coding: utf-8 -*-#
|
||||||
|
|
||||||
# YaPB - Counter-Strike Bot based on PODBot by Markus Klinge.
|
# YaPB - Counter-Strike Bot based on PODBot by Markus Klinge.
|
||||||
# Copyright © 2004-2020 YaPB Project <yapb@jeefo.net>.
|
# Copyright © 2004-2020 YaPB Project <yapb@jeefo.net>.
|
||||||
#
|
#
|
||||||
|
|
@ -14,208 +15,208 @@ import datetime, calendar
|
||||||
from github import Github
|
from github import Github
|
||||||
|
|
||||||
class BotRelease (object):
|
class BotRelease (object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
print ("Initializing Packaging")
|
print ("Initializing Packaging")
|
||||||
|
|
||||||
self.workDir = os.path.join (pathlib.Path ().absolute (), 'cfg')
|
self.workDir = os.path.join (pathlib.Path ().absolute (), 'cfg')
|
||||||
self.botDir = os.path.join (self.workDir, 'addons', 'yapb')
|
self.botDir = os.path.join (self.workDir, 'addons', 'yapb')
|
||||||
self.distDir = os.path.join (pathlib.Path ().absolute (), 'dist');
|
self.distDir = os.path.join (pathlib.Path ().absolute (), 'dist');
|
||||||
|
|
||||||
if len (sys.argv) < 2:
|
if len (sys.argv) < 2:
|
||||||
raise Exception('Missing required parameters.')
|
raise Exception('Missing required parameters.')
|
||||||
|
|
||||||
self.version = sys.argv[1]
|
self.version = sys.argv[1]
|
||||||
|
|
||||||
os.makedirs (self.distDir, exist_ok=True)
|
os.makedirs (self.distDir, exist_ok=True)
|
||||||
|
|
||||||
self.outFileWin32 = os.path.join (self.distDir, "yapb-{}-windows.zip".format (self.version))
|
self.outFileWin32 = os.path.join (self.distDir, "yapb-{}-windows.zip".format (self.version))
|
||||||
self.outFileLinux = os.path.join (self.distDir, "yapb-{}-linux.tar.xz".format (self.version))
|
self.outFileLinux = os.path.join (self.distDir, "yapb-{}-linux.tar.xz".format (self.version))
|
||||||
self.outFileMacOS = os.path.join (self.distDir, "yapb-{}-macos.zip".format (self.version))
|
self.outFileMacOS = os.path.join (self.distDir, "yapb-{}-macos.zip".format (self.version))
|
||||||
|
|
||||||
self.outFileWin32Setup = self.outFileWin32.replace ("zip", "exe")
|
self.outFileWin32Setup = self.outFileWin32.replace ("zip", "exe")
|
||||||
self.win32SetupUrl = "https://github.com/yapb/setup/releases/latest/download/botsetup.exe"
|
self.win32SetupUrl = "https://github.com/yapb/setup/releases/latest/download/botsetup.exe"
|
||||||
|
|
||||||
def makeDirs (self):
|
def makeDirs (self):
|
||||||
dirs = [
|
dirs = [
|
||||||
'bin',
|
'bin',
|
||||||
os.path.join ('data', 'pwf'),
|
os.path.join ('data', 'pwf'),
|
||||||
os.path.join ('data', 'train'),
|
os.path.join ('data', 'train'),
|
||||||
os.path.join ('data', 'graph'),
|
os.path.join ('data', 'graph'),
|
||||||
os.path.join ('data', 'logs')
|
os.path.join ('data', 'logs')
|
||||||
]
|
]
|
||||||
|
|
||||||
for dir in dirs:
|
for dir in dirs:
|
||||||
os.makedirs (os.path.join (self.botDir, dir), exist_ok=True)
|
os.makedirs (os.path.join (self.botDir, dir), exist_ok=True)
|
||||||
|
|
||||||
def download (self, fromWhere, toFile):
|
def download (self, fromWhere, toFile):
|
||||||
http = urllib3.PoolManager (10, headers = {"user-agent": "YaPB"})
|
http = urllib3.PoolManager (10, headers = {"user-agent": "YaPB"})
|
||||||
data = http.urlopen ('GET', fromWhere)
|
data = http.urlopen ('GET', fromWhere)
|
||||||
|
|
||||||
with open (toFile, "wb") as file:
|
with open (toFile, "wb") as file:
|
||||||
file.write (data.data)
|
file.write (data.data)
|
||||||
|
|
||||||
def getGraph (self, name):
|
def getGraph (self, name):
|
||||||
file = os.path.join (self.botDir, 'data', 'graph', "{}.graph".format (name))
|
file = os.path.join (self.botDir, 'data', 'graph', "{}.graph".format (name))
|
||||||
url = "http://graph.yapb.ru/graph/{}.graph".format (name);
|
url = "http://graph.yapb.ru/graph/{}.graph".format (name);
|
||||||
|
|
||||||
if os.path.exists (file):
|
if os.path.exists (file):
|
||||||
return
|
return
|
||||||
|
|
||||||
self.download (url, file)
|
self.download (url, file)
|
||||||
|
|
||||||
def getGraphs (self):
|
def getGraphs (self):
|
||||||
print ("Downloading graphs: ")
|
print ("Downloading graphs: ")
|
||||||
|
|
||||||
files = ['as_oilrig', 'cs_747', 'cs_estate', 'cs_assault', 'cs_office',
|
files = ['as_oilrig', 'cs_747', 'cs_estate', 'cs_assault', 'cs_office',
|
||||||
'cs_italy', 'cs_havana', 'cs_siege', 'cs_backalley', 'cs_militia',
|
'cs_italy', 'cs_havana', 'cs_siege', 'cs_backalley', 'cs_militia',
|
||||||
'cs_downed_cz', 'cs_havana_cz', 'cs_italy_cz', 'cs_militia_cz',
|
'cs_downed_cz', 'cs_havana_cz', 'cs_italy_cz', 'cs_militia_cz',
|
||||||
'cs_office_cz', 'de_airstrip_cz', 'de_aztec_cz', 'de_cbble_cz',
|
'cs_office_cz', 'de_airstrip_cz', 'de_aztec_cz', 'de_cbble_cz',
|
||||||
'de_chateau_cz', 'de_corruption_cz', 'de_dust_cz', 'de_dust2_cz',
|
'de_chateau_cz', 'de_corruption_cz', 'de_dust_cz', 'de_dust2_cz',
|
||||||
'de_fastline_cz', 'de_inferno_cz', 'de_piranesi_cz', 'de_prodigy_cz',
|
'de_fastline_cz', 'de_inferno_cz', 'de_piranesi_cz', 'de_prodigy_cz',
|
||||||
'de_sienna_cz', 'de_stadium_cz', 'de_tides_cz', 'de_torn_cz',
|
'de_sienna_cz', 'de_stadium_cz', 'de_tides_cz', 'de_torn_cz',
|
||||||
'de_truth_cz', 'de_vostok_cz', 'de_inferno', 'de_aztec', 'de_dust',
|
'de_truth_cz', 'de_vostok_cz', 'de_inferno', 'de_aztec', 'de_dust',
|
||||||
'de_dust2', 'de_torn', 'de_storm', 'de_airstrip', 'de_piranesi',
|
'de_dust2', 'de_torn', 'de_storm', 'de_airstrip', 'de_piranesi',
|
||||||
'de_prodigy', 'de_chateau', 'de_cbble', 'de_nuke', 'de_survivor',
|
'de_prodigy', 'de_chateau', 'de_cbble', 'de_nuke', 'de_survivor',
|
||||||
'de_vertigo', 'de_train']
|
'de_vertigo', 'de_train']
|
||||||
|
|
||||||
for file in files:
|
for file in files:
|
||||||
print (" " + file)
|
print (" " + file)
|
||||||
|
|
||||||
self.getGraph (file)
|
self.getGraph (file)
|
||||||
|
|
||||||
def unlinkBinaries (self):
|
def unlinkBinaries (self):
|
||||||
libs = ['yapb.so', 'yapb.dll', 'yapb.dylib']
|
libs = ['yapb.so', 'yapb.dll', 'yapb.dylib']
|
||||||
|
|
||||||
for lib in libs:
|
for lib in libs:
|
||||||
path = os.path.join (self.botDir, 'bin', lib)
|
path = os.path.join (self.botDir, 'bin', lib)
|
||||||
|
|
||||||
if os.path.exists (path):
|
if os.path.exists (path):
|
||||||
os.remove (path)
|
os.remove (path)
|
||||||
|
|
||||||
def copyBinary (self, path):
|
def copyBinary (self, path):
|
||||||
shutil.copy (path, os.path.join (self.botDir, 'bin'))
|
shutil.copy (path, os.path.join (self.botDir, 'bin'))
|
||||||
|
|
||||||
def zipDir (self, path, handle):
|
def zipDir (self, path, handle):
|
||||||
length = len (path) + 1
|
length = len (path) + 1
|
||||||
emptyDirs = []
|
emptyDirs = []
|
||||||
|
|
||||||
for root, dirs, files in os.walk (path):
|
for root, dirs, files in os.walk (path):
|
||||||
emptyDirs.extend ([dir for dir in dirs if os.listdir (os.path.join (root, dir)) == []])
|
emptyDirs.extend ([dir for dir in dirs if os.listdir (os.path.join (root, dir)) == []])
|
||||||
|
|
||||||
for file in files:
|
for file in files:
|
||||||
filePath = os.path.join (root, file)
|
filePath = os.path.join (root, file)
|
||||||
handle.write (filePath, filePath[length:])
|
handle.write (filePath, filePath[length:])
|
||||||
|
|
||||||
for dir in emptyDirs:
|
for dir in emptyDirs:
|
||||||
dirPath = os.path.join (root, dir)
|
dirPath = os.path.join (root, dir)
|
||||||
|
|
||||||
zif = zipfile.ZipInfo (dirPath[length:] + "/")
|
zif = zipfile.ZipInfo (dirPath[length:] + "/")
|
||||||
handle.writestr (zif, "")
|
handle.writestr (zif, "")
|
||||||
|
|
||||||
emptyDirs = []
|
emptyDirs = []
|
||||||
|
|
||||||
def generateZip (self, dir):
|
def generateZip (self, dir):
|
||||||
zipFile = zipfile.ZipFile (dir, 'w', zipfile.ZIP_DEFLATED)
|
zipFile = zipfile.ZipFile (dir, 'w', zipfile.ZIP_DEFLATED)
|
||||||
zipFile.comment = bytes (self.version, encoding = "ascii")
|
zipFile.comment = bytes (self.version, encoding = "ascii")
|
||||||
|
|
||||||
self.zipDir (self.workDir, zipFile)
|
self.zipDir (self.workDir, zipFile)
|
||||||
zipFile.close ()
|
zipFile.close ()
|
||||||
|
|
||||||
def convertZipToTXZ (self, zip, txz):
|
def convertZipToTXZ (self, zip, txz):
|
||||||
timeshift = int ((datetime.datetime.now () - datetime.datetime.utcnow ()).total_seconds ())
|
timeshift = int ((datetime.datetime.now () - datetime.datetime.utcnow ()).total_seconds ())
|
||||||
|
|
||||||
with zipfile.ZipFile (zip) as zipf:
|
with zipfile.ZipFile (zip) as zipf:
|
||||||
with tarfile.open (txz, 'w:xz') as tarf:
|
with tarfile.open (txz, 'w:xz') as tarf:
|
||||||
for zif in zipf.infolist ():
|
for zif in zipf.infolist ():
|
||||||
tif = tarfile.TarInfo (name = zif.filename)
|
tif = tarfile.TarInfo (name = zif.filename)
|
||||||
tif.size = zif.file_size
|
tif.size = zif.file_size
|
||||||
tif.mtime = calendar.timegm (zif.date_time) - timeshift
|
tif.mtime = calendar.timegm (zif.date_time) - timeshift
|
||||||
|
|
||||||
tarf.addfile (tarinfo = tif, fileobj = zipf.open (zif.filename))
|
tarf.addfile (tarinfo = tif, fileobj = zipf.open (zif.filename))
|
||||||
|
|
||||||
os.remove (zip)
|
os.remove (zip)
|
||||||
|
|
||||||
def generateWin32 (self):
|
def generateWin32 (self):
|
||||||
print ("Generating Win32 ZIP")
|
print ("Generating Win32 ZIP")
|
||||||
|
|
||||||
binary = os.path.join ('build_x86_win32', 'yapb.dll')
|
binary = os.path.join ('build_x86_win32', 'yapb.dll')
|
||||||
|
|
||||||
if not os.path.exists (binary):
|
if not os.path.exists (binary):
|
||||||
return
|
return
|
||||||
|
|
||||||
self.unlinkBinaries ()
|
self.unlinkBinaries ()
|
||||||
|
|
||||||
self.copyBinary (binary)
|
self.copyBinary (binary)
|
||||||
self.generateZip (self.outFileWin32)
|
self.generateZip (self.outFileWin32)
|
||||||
|
|
||||||
self.download (self.win32SetupUrl, "botsetup.exe")
|
self.download (self.win32SetupUrl, "botsetup.exe")
|
||||||
|
|
||||||
print ("Generating Win32 EXE")
|
print ("Generating Win32 EXE")
|
||||||
|
|
||||||
with open ("botsetup.exe", "rb") as sfx, open (self.outFileWin32, "rb") as zip, open (self.outFileWin32Setup, "wb") as exe:
|
with open ("botsetup.exe", "rb") as sfx, open (self.outFileWin32, "rb") as zip, open (self.outFileWin32Setup, "wb") as exe:
|
||||||
exe.write (sfx.read ())
|
exe.write (sfx.read ())
|
||||||
exe.write (zip.read ())
|
exe.write (zip.read ())
|
||||||
|
|
||||||
def generateLinux (self):
|
def generateLinux (self):
|
||||||
print ("Generating Linux TXZ")
|
print ("Generating Linux TXZ")
|
||||||
|
|
||||||
binary = os.path.join ('build_x86_linux', 'yapb.so');
|
binary = os.path.join ('build_x86_linux', 'yapb.so');
|
||||||
|
|
||||||
if not os.path.exists (binary):
|
if not os.path.exists (binary):
|
||||||
return
|
return
|
||||||
|
|
||||||
self.unlinkBinaries ()
|
self.unlinkBinaries ()
|
||||||
self.copyBinary (binary)
|
self.copyBinary (binary)
|
||||||
|
|
||||||
tmpFile = "tmp.zip"
|
tmpFile = "tmp.zip"
|
||||||
|
|
||||||
self.generateZip (tmpFile)
|
self.generateZip (tmpFile)
|
||||||
self.convertZipToTXZ (tmpFile, self.outFileLinux)
|
self.convertZipToTXZ (tmpFile, self.outFileLinux)
|
||||||
|
|
||||||
def generateMac (self):
|
def generateMac (self):
|
||||||
print ("Generating macOS ZIP")
|
print ("Generating macOS ZIP")
|
||||||
|
|
||||||
binary = os.path.join ('build_x86_macos', 'yapb.dylib')
|
binary = os.path.join ('build_x86_macos', 'yapb.dylib')
|
||||||
|
|
||||||
if not os.path.exists (binary):
|
if not os.path.exists (binary):
|
||||||
return
|
return
|
||||||
|
|
||||||
self.unlinkBinaries ()
|
self.unlinkBinaries ()
|
||||||
self.copyBinary (binary)
|
self.copyBinary (binary)
|
||||||
|
|
||||||
self.generateZip (self.outFileMacOS)
|
self.generateZip (self.outFileMacOS)
|
||||||
|
|
||||||
def generate (self):
|
def generate (self):
|
||||||
self.generateWin32 ()
|
self.generateWin32 ()
|
||||||
self.generateLinux ()
|
self.generateLinux ()
|
||||||
self.generateMac ()
|
self.generateMac ()
|
||||||
|
|
||||||
def createRelease (self, repository, version):
|
def createRelease (self, repository, version):
|
||||||
print ("Creating Github Tag")
|
print ("Creating Github Tag")
|
||||||
|
|
||||||
releases = [self.outFileLinux, self.outFileWin32, self.outFileMacOS, self.outFileWin32Setup]
|
releases = [self.outFileLinux, self.outFileWin32, self.outFileMacOS, self.outFileWin32Setup]
|
||||||
|
|
||||||
for release in releases:
|
for release in releases:
|
||||||
if not os.path.exists (release):
|
if not os.path.exists (release):
|
||||||
return
|
return
|
||||||
|
|
||||||
releaseName = "YaPB " + version
|
releaseName = "YaPB " + version
|
||||||
releaseMessage = repository.get_commits()[0].commit.message
|
releaseMessage = repository.get_commits()[0].commit.message
|
||||||
releaseSha = repository.get_commits()[0].sha;
|
releaseSha = repository.get_commits()[0].sha;
|
||||||
|
|
||||||
ghr = repository.create_git_tag_and_release (tag = version, tag_message = version, release_name = releaseName, release_message = releaseMessage, type='commit', object = releaseSha, draft = False)
|
ghr = repository.create_git_tag_and_release (tag = version, tag_message = version, release_name = releaseName, release_message = releaseMessage, type='commit', object = releaseSha, draft = False)
|
||||||
|
|
||||||
print ("Uploading packages to Github")
|
print ("Uploading packages to Github")
|
||||||
|
|
||||||
for release in releases:
|
for release in releases:
|
||||||
ghr.upload_asset( path = release, label = os.path.basename (release))
|
ghr.upload_asset( path = release, label = os.path.basename (release))
|
||||||
|
|
||||||
def uploadGithub (self):
|
def uploadGithub (self):
|
||||||
gh = Github (os.environ["GITHUB_TOKEN"])
|
gh = Github (os.environ["GITHUB_TOKEN"])
|
||||||
repo = gh.get_repo ("yapb/yapb")
|
repo = gh.get_repo ("yapb/yapb")
|
||||||
|
|
||||||
self.createRelease (repo, self.version)
|
self.createRelease (repo, self.version)
|
||||||
|
|
||||||
release = BotRelease ()
|
release = BotRelease ()
|
||||||
|
|
||||||
release.makeDirs ()
|
release.makeDirs ()
|
||||||
|
|
|
||||||
|
|
@ -572,7 +572,7 @@ void Bot::updatePickups () {
|
||||||
allowPickup = true;
|
allowPickup = true;
|
||||||
pickupType = Pickup::DefusalKit;
|
pickupType = Pickup::DefusalKit;
|
||||||
}
|
}
|
||||||
else if (strncmp ("grenade", classname, 7) == 0 && strcmp (model, "c4.mdl") == 0) {
|
else if (strncmp ("grenade", classname, 7) == 0 && conf.getBombModelName () == model) {
|
||||||
allowPickup = true;
|
allowPickup = true;
|
||||||
pickupType = Pickup::PlantedC4;
|
pickupType = Pickup::PlantedC4;
|
||||||
}
|
}
|
||||||
|
|
@ -2888,7 +2888,7 @@ void Bot::checkDarkness () {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bot::checkParachute () {
|
void Bot::checkParachute () {
|
||||||
static auto parachute = engfuncs.pfnCVarGetPointer ("sv_parachute");
|
static auto parachute = engfuncs.pfnCVarGetPointer (conf.fetchCustom ("AMXParachuteCvar").chars ());
|
||||||
|
|
||||||
// if no cvar or it's not enabled do not bother
|
// if no cvar or it's not enabled do not bother
|
||||||
if (parachute && parachute->value > 0.0f) {
|
if (parachute && parachute->value > 0.0f) {
|
||||||
|
|
@ -5460,7 +5460,7 @@ edict_t *Bot::correctGrenadeVelocity (const char *model) {
|
||||||
edict_t *result = nullptr;
|
edict_t *result = nullptr;
|
||||||
|
|
||||||
game.searchEntities ("classname", "grenade", [&] (edict_t *ent) {
|
game.searchEntities ("classname", "grenade", [&] (edict_t *ent) {
|
||||||
if (ent->v.owner == this->ent () && strcmp (ent->v.model.chars (9), model) == 0) {
|
if (ent->v.owner == this->ent () && util.isModel (ent, model)) {
|
||||||
result = ent;
|
result = ent;
|
||||||
|
|
||||||
// set the correct velocity for the grenade
|
// set the correct velocity for the grenade
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ void Bot::prepareChatMessage (StringRef message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the humanized name out of client
|
// get the humanized name out of client
|
||||||
auto humanizedName = [] (int index) -> StringRef {
|
auto humanizedName = [] (int index) -> String {
|
||||||
auto ent = game.playerOfIndex (index);
|
auto ent = game.playerOfIndex (index);
|
||||||
|
|
||||||
if (!util.isPlayer (ent)) {
|
if (!util.isPlayer (ent)) {
|
||||||
|
|
@ -157,7 +157,7 @@ void Bot::prepareChatMessage (StringRef message) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// find highfrag player
|
// find highfrag player
|
||||||
auto getHighfragPlayer = [&] () -> StringRef {
|
auto getHighfragPlayer = [&] () -> String {
|
||||||
int highestFrags = -1;
|
int highestFrags = -1;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
|
|
@ -178,7 +178,7 @@ void Bot::prepareChatMessage (StringRef message) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// get roundtime
|
// get roundtime
|
||||||
auto getRoundTime = [] () -> StringRef {
|
auto getRoundTime = [] () -> String {
|
||||||
auto roundTimeSecs = static_cast <int> (bots.getRoundEndTime () - game.time ());
|
auto roundTimeSecs = static_cast <int> (bots.getRoundEndTime () - game.time ());
|
||||||
|
|
||||||
String roundTime;
|
String roundTime;
|
||||||
|
|
@ -188,12 +188,12 @@ void Bot::prepareChatMessage (StringRef message) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// get bot's victim
|
// get bot's victim
|
||||||
auto getMyVictim = [&] () -> StringRef {;
|
auto getMyVictim = [&] () -> String {;
|
||||||
return humanizedName (game.indexOfPlayer (m_lastVictim));
|
return humanizedName (game.indexOfPlayer (m_lastVictim));
|
||||||
};
|
};
|
||||||
|
|
||||||
// get the game name alias
|
// get the game name alias
|
||||||
auto getGameName = [] () -> StringRef {
|
auto getGameName = [] () -> String {
|
||||||
String gameName;
|
String gameName;
|
||||||
|
|
||||||
if (game.is (GameFlags::ConditionZero)) {
|
if (game.is (GameFlags::ConditionZero)) {
|
||||||
|
|
@ -216,7 +216,7 @@ void Bot::prepareChatMessage (StringRef message) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// get enemy or teammate alive
|
// get enemy or teammate alive
|
||||||
auto getPlayerAlive = [&] (bool needsEnemy) -> StringRef {
|
auto getPlayerAlive = [&] (bool needsEnemy) -> String {
|
||||||
for (const auto &client : util.getClients ()) {
|
for (const auto &client : util.getClients ()) {
|
||||||
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive) || client.ent == ent ()) {
|
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive) || client.ent == ent ()) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
//
|
//
|
||||||
// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge.
|
// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge.
|
||||||
// Copyright Š 2004-2020 YaPB Project <yapb@jeefo.net>.
|
// Copyright © 2004-2020 YaPB Project <yapb@jeefo.net>.
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
//
|
//
|
||||||
|
|
@ -28,6 +28,7 @@ void BotConfig::loadConfigs () {
|
||||||
loadLogosConfig ();
|
loadLogosConfig ();
|
||||||
loadAvatarsConfig ();
|
loadAvatarsConfig ();
|
||||||
loadDifficultyConfig ();
|
loadDifficultyConfig ();
|
||||||
|
loadCustomConfig ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotConfig::loadMainConfig (bool isFirstLoad) {
|
void BotConfig::loadMainConfig (bool isFirstLoad) {
|
||||||
|
|
@ -614,6 +615,38 @@ void BotConfig::loadMapSpecificConfig () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BotConfig::loadCustomConfig () {
|
||||||
|
String line;
|
||||||
|
MemFile file;
|
||||||
|
|
||||||
|
m_custom["C4ModelName"] = "c4.mdl";
|
||||||
|
m_custom["AMXParachuteCvar"] = "sv_parachute";
|
||||||
|
|
||||||
|
// custom inititalization
|
||||||
|
if (util.openConfig ("custom.cfg", "Custom config file not found. Loading defaults.", &file)) {
|
||||||
|
m_custom.clear ();
|
||||||
|
|
||||||
|
while (file.getLine (line)) {
|
||||||
|
line.trim ();
|
||||||
|
|
||||||
|
if (isCommentLine (line)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto values = line.split ("=");
|
||||||
|
|
||||||
|
if (values.length () != 2) {
|
||||||
|
logger.error ("Bad configuration for custom.cfg");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto kv = Twin <String, String> (values[0].trim (), values[1].trim ());
|
||||||
|
|
||||||
|
if (!kv.first.empty () && !kv.second.empty ()) {
|
||||||
|
m_custom[kv.first] = kv.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BotConfig::loadLogosConfig () {
|
void BotConfig::loadLogosConfig () {
|
||||||
setupMemoryFiles ();
|
setupMemoryFiles ();
|
||||||
|
|
||||||
|
|
@ -750,6 +783,14 @@ const char *BotConfig::translate (StringRef input) {
|
||||||
return input.chars (); // nothing found
|
return input.chars (); // nothing found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BotConfig::showCustomValues () {
|
||||||
|
game.print ("Current values for custom config items:");
|
||||||
|
|
||||||
|
m_custom.foreach ([&](const String &key, const String &val) {
|
||||||
|
game.print (" %s = %s", key, val);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
uint32 BotConfig::hashLangString (StringRef str) {
|
uint32 BotConfig::hashLangString (StringRef str) {
|
||||||
auto test = [] (const char ch) {
|
auto test = [] (const char ch) {
|
||||||
return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
|
return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
|
||||||
|
|
|
||||||
|
|
@ -262,6 +262,14 @@ int BotControl::cmdCvars () {
|
||||||
return BotCommandResult::Handled;
|
return BotCommandResult::Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int BotControl::cmdShowCustom () {
|
||||||
|
enum args { alias = 1 };
|
||||||
|
|
||||||
|
conf.showCustomValues ();
|
||||||
|
|
||||||
|
return BotCommandResult::Handled;
|
||||||
|
}
|
||||||
|
|
||||||
int BotControl::cmdNode () {
|
int BotControl::cmdNode () {
|
||||||
enum args { root, alias, cmd, cmd2 };
|
enum args { root, alias, cmd, cmd2 };
|
||||||
|
|
||||||
|
|
@ -1895,6 +1903,7 @@ BotControl::BotControl () {
|
||||||
m_cmds.emplace ("list/listbots", "list [noarguments]", "Lists the bots currently playing on server.", &BotControl::cmdList);
|
m_cmds.emplace ("list/listbots", "list [noarguments]", "Lists the bots currently playing on server.", &BotControl::cmdList);
|
||||||
m_cmds.emplace ("graph/g/wp/wpt/waypoint", "graph [help]", "Handles graph operations.", &BotControl::cmdNode);
|
m_cmds.emplace ("graph/g/wp/wpt/waypoint", "graph [help]", "Handles graph operations.", &BotControl::cmdNode);
|
||||||
m_cmds.emplace ("cvars", "cvars [save|cvar]", "Display all the cvars with their descriptions.", &BotControl::cmdCvars);
|
m_cmds.emplace ("cvars", "cvars [save|cvar]", "Display all the cvars with their descriptions.", &BotControl::cmdCvars);
|
||||||
|
m_cmds.emplace ("show_custom", "show_custom [noarguments]", "Show's the curent values from custom.cfg.", &BotControl::cmdShowCustom);
|
||||||
|
|
||||||
// declare the menus
|
// declare the menus
|
||||||
createMenus ();
|
createMenus ();
|
||||||
|
|
|
||||||
|
|
@ -799,6 +799,9 @@ bool Game::postload () {
|
||||||
// set out user agent for http stuff
|
// set out user agent for http stuff
|
||||||
http.setUserAgent (strings.format ("%s/%s", product.name, product.version));
|
http.setUserAgent (strings.format ("%s/%s", product.name, product.version));
|
||||||
|
|
||||||
|
// startup the sockets
|
||||||
|
http.startup ();
|
||||||
|
|
||||||
// set the app name
|
// set the app name
|
||||||
plat.setAppName (product.name.chars ());
|
plat.setAppName (product.name.chars ());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2806,9 +2806,10 @@ void BotGraph::setBombOrigin (bool reset, const Vector &pos) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool wasFound = false;
|
bool wasFound = false;
|
||||||
|
auto bombModel = conf.getBombModelName ();
|
||||||
|
|
||||||
game.searchEntities ("classname", "grenade", [&] (edict_t *ent) {
|
game.searchEntities ("classname", "grenade", [&] (edict_t *ent) {
|
||||||
if (strcmp (ent->v.model.chars (9), "c4.mdl") == 0) {
|
if (util.isModel (ent, bombModel)) {
|
||||||
m_bombOrigin = game.getEntityWorldOrigin (ent);
|
m_bombOrigin = game.getEntityWorldOrigin (ent);
|
||||||
wasFound = true;
|
wasFound = true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1628,10 +1628,13 @@ void BotManager::updateActiveGrenade () {
|
||||||
}
|
}
|
||||||
m_activeGrenades.clear (); // clear previously stored grenades
|
m_activeGrenades.clear (); // clear previously stored grenades
|
||||||
|
|
||||||
|
// need to ignore bomb model in active grenades...
|
||||||
|
auto bombModel = conf.getBombModelName ();
|
||||||
|
|
||||||
// search the map for any type of grenade
|
// search the map for any type of grenade
|
||||||
game.searchEntities ("classname", "grenade", [&] (edict_t *e) {
|
game.searchEntities ("classname", "grenade", [&] (edict_t *e) {
|
||||||
// do not count c4 as a grenade
|
// do not count c4 as a grenade
|
||||||
if (strcmp (e->v.model.chars (9), "c4.mdl") != 0) {
|
if (!util.isModel (e, bombModel)) {
|
||||||
m_activeGrenades.push (e);
|
m_activeGrenades.push (e);
|
||||||
}
|
}
|
||||||
return EntitySearchResult::Continue; // continue iteration
|
return EntitySearchResult::Continue; // continue iteration
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ int Bot::findBestGoal () {
|
||||||
int result = kInvalidNodeIndex;
|
int result = kInvalidNodeIndex;
|
||||||
|
|
||||||
game.searchEntities ("classname", "weaponbox", [&] (edict_t *ent) {
|
game.searchEntities ("classname", "weaponbox", [&] (edict_t *ent) {
|
||||||
if (strcmp (ent->v.model.chars (9), "backpack.mdl") == 0) {
|
if (util.isModel (ent, "backpack.mdl")) {
|
||||||
result = graph.getNearest (game.getEntityWorldOrigin (ent));
|
result = graph.getNearest (game.getEntityWorldOrigin (ent));
|
||||||
|
|
||||||
if (graph.exists (result)) {
|
if (graph.exists (result)) {
|
||||||
|
|
@ -2965,11 +2965,13 @@ int Bot::getNearestToPlantedBomb () {
|
||||||
if (!game.mapIs (MapFlags::Demolition)) {
|
if (!game.mapIs (MapFlags::Demolition)) {
|
||||||
return kInvalidNodeIndex; // don't search for bomb if the player is CT, or it's not defusing bomb
|
return kInvalidNodeIndex; // don't search for bomb if the player is CT, or it's not defusing bomb
|
||||||
}
|
}
|
||||||
int result = kInvalidNodeIndex;
|
|
||||||
|
auto bombModel = conf.getBombModelName ();
|
||||||
|
auto result = kInvalidNodeIndex;
|
||||||
|
|
||||||
// search the bomb on the map
|
// search the bomb on the map
|
||||||
game.searchEntities ("classname", "grenade", [&result] (edict_t *ent) {
|
game.searchEntities ("classname", "grenade", [&result, &bombModel] (edict_t *ent) {
|
||||||
if (strcmp (ent->v.model.chars (9), "c4.mdl") == 0) {
|
if (util.isModel (ent, bombModel)) {
|
||||||
result = graph.getNearest (game.getEntityWorldOrigin (ent));
|
result = graph.getNearest (game.getEntityWorldOrigin (ent));
|
||||||
|
|
||||||
if (graph.exists (result)) {
|
if (graph.exists (result)) {
|
||||||
|
|
|
||||||
|
|
@ -687,6 +687,10 @@ bool BotSupport::isObjectInsidePlane (FrustumPlane &plane, const Vector ¢er,
|
||||||
return isPointInsidePlane (top) || isPointInsidePlane (bottom);
|
return isPointInsidePlane (top) || isPointInsidePlane (bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BotSupport::isModel (const edict_t *ent, StringRef model) {
|
||||||
|
return model == ent->v.model.chars (9);
|
||||||
|
}
|
||||||
|
|
||||||
int32 BotSupport::sendTo (int socket, const void *message, size_t length, int flags, const sockaddr *dest, int destLength) {
|
int32 BotSupport::sendTo (int socket, const void *message, size_t length, int flags, const sockaddr *dest, int destLength) {
|
||||||
const auto send = [&] (const Twin <const uint8 *, size_t> &msg) -> int32 {
|
const auto send = [&] (const Twin <const uint8 *, size_t> &msg) -> int32 {
|
||||||
return Socket::sendto (socket, msg.first, msg.second, flags, dest, destLength);
|
return Socket::sendto (socket, msg.first, msg.second, flags, dest, destLength);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue