Merge pull request #2 from gtteamamxx/menu_handler

Merge master into menu_handler
This commit is contained in:
Karol Szuster 2018-11-05 21:47:23 +01:00 committed by GitHub
commit 550a44d877
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
374 changed files with 138483 additions and 35249 deletions

74
.github/CONTRIBUTING.md vendored Normal file
View File

@ -0,0 +1,74 @@
# Contributing to AMX Mod X
## Issue reports
Please consider the following guidelines when reporting an issue.
#### Not for general support
This is not the right place to get help with using or installing AMX Mod X, or for issues with specific, third-party AMX Mod X plugins or extensions.
For help with AMX Mod X, please consult the [AlliedModders forums](https://forums.alliedmods.net/forumdisplay.php?f=3). Similarly, for assistance with, or to report issues with, third-party AMX Mod X plugins or extensions, you should post in the existing thread for that plugin or extension on the [AlliedModders forums](https://forums.alliedmods.net/forumdisplay.php?f=3).
#### Details, details, details
Provide as much detail as possible when reporting an issue.
For bugs or other undesired behavior, answers to the following questions are a great start:
* What is the issue?
* What behavior are you expecting instead?
* On what operating system is the game server running?
* What game is the game server running?
* What exact versions (full x.y.z.a version number) of Metamod and AMX Mod X are installed on the game server?
* What is the specific, shortest path to reproducing this issue? If this issue can be reproduced with plugin code, please try to shorten it to the minimum required to trigger the problem.
If this is a feature request, the following are helpful. Generally, not all will apply, but whatever you can answer ahead of time will shorten back and forth conversation.
* What is your end goal, or what are you trying to accomplish?
* Why is this necessary, or what benefit do you see with it?
* Will this be useful to others?
#### Issues with security implications
Please report any security bugs to [security@alliedmods.net](mailto:security@alliedmods.net) rather than to this public issue tracker.
#### We're only human
Please keep in mind that we maintain this project in our spare time, at no cost. There is no SLA, and you are not owed a response or a fix.
#### Conduct
Please refer to the [AlliedModders forum rules.](https://forums.alliedmods.net/misc.php?do=showrules)
## Pull Requests
Firstly, thank you for considering contributing changes to the project!
However, if this is anything more than a small fix such as a gamedata update, a glaring code flaw, or a simple typo in a file like this one, please file an issue first so that it can be discussed, unless you have already spoken to multiple members of the development team about it on IRC or the AlliedModders forums.
We don't like to have to reject pull requests, so we want to avoid those scenarios. We wouldn't want you to feel like you wasted your time writing something only for us to shoot it down.
#### Rejection
*Copied from Phabricator's [Contributing Code guidelines](https://secure.phabricator.com/book/phabcontrib/article/contributing_code/#rejecting-patches), as we largely feel the same way about this.*
> If you send us a patch without coordinating it with us first, it will probably be immediately rejected, or sit in limbo for a long time and eventually be rejected. The reasons we do this vary from patch to patch, but some of the most common reasons are:
>
> **Unjustifiable Costs**: We support code in the upstream forever. Support is enormously expensive and takes up a huge amount of our time. The cost to support a change over its lifetime is often 10x or 100x or 1000x greater than the cost to write the first version of it. Many uncoordinated patches we receive are "white elephants", which would cost much more to maintain than the value they provide.
>
> As an author, it may look like you're giving us free work and we're rejecting it as too expensive, but this viewpoint doesn't align with the reality of a large project which is actively supported by a small, experienced team. Writing code is cheap; maintaining it is expensive.
>
> By coordinating with us first, you can make sure the patch is something we consider valuable enough to put long-term support resources behind, and that you're building it in a way that we're comfortable taking over.
>
> **Not a Good Fit**: Many patches aren't good fits for the upstream: they implement features we simply don't want. You can find more information in Contributing Feature Requests. Coordinating with us first helps make sure we're on the same page and interested in a feature.
>
> The most common type of patch along these lines is a patch which adds new configuration options. We consider additional configuration options to have an exceptionally high lifetime support cost and are very unlikely to accept them. Coordinate with us first.
>
> **Not a Priority**: If you send us a patch against something which isn't a priority, we probably won't have time to look at it. We don't give special treatment to low-priority issues just because there's code written: we'd still be spending time on something lower-priority when we could be spending it on something higher-priority instead.
>
> If you coordinate with us first, you can make sure your patch is in an area of the codebase that we can prioritize.
>
> **Overly Ambitious Patches**: Sometimes we'll get huge patches from new contributors. These can have a lot of fundamental problems and require a huge amount of our time to review and correct. If you're interested in contributing, you'll have more success if you start small and learn as you go.
>
> We can help you break a large change into smaller pieces and learn how the codebase works as you proceed through the implementation, but only if you coordinate with us first.
>
> **Generality**: We often receive several feature requests which ask for similar features, and can come up with a general approach which covers all of the use cases. If you send us a patch for your use case only, the approach may be too specific. When a cleaner and more general approach is available, we usually prefer to pursue it.
>
> By coordinating with us first, we can make you aware of similar use cases and opportunities to generalize an approach. These changes are often small, but can have a big impact on how useful a piece of code is.
>
> **Infrastructure and Sequencing**: Sometimes patches are written against a piece of infrastructure with major planned changes. We don't want to accept these because they'll make the infrastructure changes more difficult to implement.
>
> Coordinate with us first to make sure a change doesn't need to wait on other pieces of infrastructure. We can help you identify technical blockers and possibly guide you through resolving them if you're interested.

25
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,25 @@
# Help us help you
- [ ] I have checked that my issue [doesn't exist yet](https://github.com/alliedmodders/amxmodx/issues).
- [ ] I have tried my absolute best to reduce the problem-space and have provided the absolute smallest test-case possible.
- [ ] I can always reproduce the issue with the provided description below.
# Environment
* Operating System version:
* Game/AppID (with version if applicable):
* Current AMX Mod X version:
* Current Metamod version:
- [ ] I have updated AMX Mod X to the [latest version](https://www.amxmodx.org/downloads.php) and it still happens.
- [ ] I have updated AMX Mod X to the [latest snapshot](https://www.amxmodx.org/snapshots.php) and it still happens.
- [ ] I have updated Metamod to the [latest version](https://www.amxmodx.org/downloads.php) and it still happens.
# Description
# Problematic Code (or Steps to Reproduce)
```PAWN
// TODO(you): code here to reproduce the problem
```
# Logs
* Please attach in separate files: game output, library logs, kernel logs, and any other supporting information.
* In case of a crash, please attach minidump or dump analyze output.

2
.gitignore vendored
View File

@ -84,3 +84,5 @@ Thumbs.db
# AMXX plugin build related files
plugins/compile.dat
plugins/compiled/
build_deps/

View File

@ -8,6 +8,7 @@ addons:
- linux-libc-dev
- gcc-multilib
- g++-multilib
- nasm
sources:
- llvm-toolchain-precise-3.7
- ubuntu-toolchain-r-test
@ -18,9 +19,9 @@ compiler:
before_script:
- CHECKOUT_DIR=$PWD && cd ..
- chmod a+x $CHECKOUT_DIR/support/checkout-deps.sh
- $CHECKOUT_DIR/support/checkout-deps.sh --no-mysql && cd $CHECKOUT_DIR
- $CHECKOUT_DIR/support/checkout-deps.sh && cd $CHECKOUT_DIR
script:
- mkdir build && cd build
- PATH="~/.local/bin:$PATH"
- CC=clang-3.7 CXX=clang-3.7 python ../configure.py --enable-optimize --no-mysql
- CC=clang-3.7 CXX=clang-3.7 python ../configure.py --enable-optimize
- ambuild

View File

@ -17,8 +17,10 @@ class AMXXConfig(object):
self.versionlib = None
self.zlib = None
self.hashing = None
self.utf8rewind = None
self.csx_app = None
self.stdcxx_path = None
self.nasm_path = None
def use_auto_versioning(self):
if builder.backend != 'amb2':
@ -87,7 +89,7 @@ class AMXXConfig(object):
mysql_path = builder.options.mysql_path
if not len(mysql_path):
mysql_path = os.getenv('MYSQL5', '')
mysql_path = os.getenv('MYSQL55', '')
if len(mysql_path):
self.mysql_path = os.path.join(builder.originalCwd, mysql_path)
@ -95,7 +97,7 @@ class AMXXConfig(object):
raise Exception('Metamod path does not exist: {0}'.format(mysql_path))
else:
try_paths = [
os.path.join(builder.sourcePath, '..', 'mysql-5.0'),
os.path.join(builder.sourcePath, '..', 'mysql-5.5'),
]
for try_path in try_paths:
if os.path.exists(try_path):
@ -104,6 +106,31 @@ class AMXXConfig(object):
if not self.mysql_path:
raise Exception('Could not find MySQL! Try passing --mysql to configure.py.')
def detectNASM(self):
import subprocess
nasm_paths = [
getattr(builder.options, 'nasm_path', 'nasm'),
]
if builder.target_platform == 'windows':
nasm_paths += [os.path.join(
builder.sourcePath,
'build_deps',
'nasm',
'nasm.exe')
]
for nasm_path in nasm_paths:
try:
subprocess.check_output([nasm_path, '-v'])
self.nasm_path = nasm_path
break
except:
pass
if self.nasm_path is None:
raise Exception('Could not find a suitable path for nasm')
# Returns list of lines of output from the compiler
@staticmethod
def invokeCompiler(args):
@ -164,6 +191,7 @@ class AMXXConfig(object):
cxx.includes += [os.path.join(builder.sourcePath, 'third_party')]
cxx.includes += [os.path.join(builder.sourcePath, 'third_party', 'hashing')]
cxx.includes += [os.path.join(builder.sourcePath, 'third_party', 'zlib')]
cxx.includes += [os.path.join(builder.sourcePath, 'third_party', 'utf8rewind')]
def configure_gcc(self, cxx):
cxx.cflags += [
@ -206,6 +234,10 @@ class AMXXConfig(object):
cxx.cflags += ['-Wno-sometimes-uninitialized']
if builder.target_platform == 'linux' and cxx.version >= '3.6':
cxx.cxxflags += ['-Wno-inconsistent-missing-override']
if builder.target_platform == 'linux' and cxx.version >= '3.9':
cxx.cxxflags += ['-Wno-varargs']
if builder.target_platform == 'linux' and cxx.version >= '4.0':
cxx.cxxflags += ['-Wno-address-of-packed-member']
if have_gcc:
cxx.cflags += ['-Wno-parentheses']
@ -259,6 +291,9 @@ class AMXXConfig(object):
'odbccp32.lib',
]
if cxx.version >= 1900:
cxx.linkflags += ['legacy_stdio_definitions.lib', 'legacy_stdio_wide_specifiers.lib']
if builder.options.opt == '1':
cxx.cflags += ['/Ox']
cxx.linkflags += ['/OPT:ICF', '/OPT:REF']
@ -363,11 +398,42 @@ class AMXXConfig(object):
binary = context.compiler.Program(name)
return self.AddVersioning(binary)
def AddAssembly(self, context, binary, input_file, output_file, includes=[], extra_argv=[]):
if builder.target_platform == 'windows':
obj_type = 'win32'
elif builder.target_platform == 'linux':
obj_type = 'elf32'
elif builder.target_platform == 'mac':
obj_type = 'macho32'
input_path = os.path.join(context.currentSourcePath, input_file)
output_path = output_file
argv = [
self.nasm_path,
'-I{0}{1}'.format(context.currentSourcePath, os.sep),
input_path,
'-f', obj_type,
'-o', output_path,
] + extra_argv
extra_includes = []
for include_file in includes:
extra_includes.append(os.path.join(context.currentSourcePath, include_file))
cmd_node, output_nodes = context.AddCommand(
inputs = [input_path] + extra_includes,
argv = argv,
outputs = [output_path])
binary.compiler.linkflags += [output_nodes[0]]
AMXX = AMXXConfig()
AMXX.detectProductVersion()
AMXX.detectMetamod()
AMXX.detectHlsdk()
AMXX.detectMysql()
AMXX.detectNASM()
AMXX.configure()
if AMXX.use_auto_versioning():
@ -388,6 +454,10 @@ AMXX.hashing = builder.RunScript(
'third_party/hashing/AMBuilder'
)
AMXX.utf8rewind = builder.RunScript(
'third_party/utf8rewind/AMBuilder'
)
builder.RunBuildScripts(
[
'amxmodx/AMBuilder',
@ -402,6 +472,7 @@ builder.RunBuildScripts(
'modules/fun/AMBuilder',
'modules/geoip/AMBuilder',
'modules/hamsandwich/AMBuilder',
'modules/json/AMBuilder',
'modules/mysqlx/AMBuilder',
'modules/ns/AMBuilder',
'modules/nvault/AMBuilder',

View File

@ -1,18 +1,22 @@
AMX Mod X
=========
AMX Mod X - Half-Life 1 Scripting and Server Administration
<p align="center">
<img src="https://github.com/alliedmodders/amxmodx/blob/master/editor/studio/AMXXLarge.bmp"/>
</p>
**AMX Mod X** is a [Metamod](https://github.com/jkivilin/metamod-p) plugin for [Half-Life 1](https://github.com/ValveSoftware/halflife). It provides comprehensive scripting for the game engine and its mods. Scripts can intercept network messages, log events, commands, client commands, set cvars, modify entities, and more. AMX Mod X also has a system for extending native scripting through modules, leading to outside support for things like MySQL and Sockets.
General
-------
- [AMXX website](http://www.amxmodx.org/)
- [AMXX website](https://amxmodx.org/)
- [Forum](https://forums.alliedmods.net/forumdisplay.php?f=3): Discussion forum including plugin/extension development
- [General documentation](https://wiki.alliedmods.net/Category:Documentation_%28AMX_Mod_X%29): Miscellaneous information about AMXX
- [Latest release](http://www.amxmodx.org/downloads.php): The latest stable AMXX release
- [Build snapshots](http://www.amxmodx.org/snapshots.php): Builds of recent development versions
- [Latest release](https://amxmodx.org/downloads.php): The latest stable AMXX release
- [Build snapshots](https://www.amxmodx.org/downloads-new.php): Builds of recent development versions
Development
-----------
- [Issue tracker](https://bugs.alliedmods.net): Issues that require back and forth communication
- [Issue tracker](https://github.com/alliedmodders/amxmodx/issues): Issues that require back and forth communication
- [Issue archive](https://bugs.alliedmods.net/describecomponents.cgi?product=AMX%20Mod%20X): Old issue tracker (read-only)
- [Building AMXX](https://wiki.alliedmods.net/Building_AMX_Mod_X): Instructions on how to build AMXX itself using [AMBuild](https://github.com/alliedmodders/ambuild)
- [AMX Mod X API](https://amxmodx.org/api/): AMX Mod X API reference generated from include files
- [AMXX scripting](https://wiki.alliedmods.net/Category:Scripting_(AMX_Mod_X)): Pawn examples and introduction to the language

View File

@ -9,35 +9,26 @@ binary.compiler.defines += [
'HAVE_STDINT_H',
]
if builder.target_platform == 'mac':
jit_objects = [
binary.Dep('JIT/amxexecn-darwin.o'),
binary.Dep('JIT/amxjitsn-darwin.o'),
binary.Dep('JIT/natives-darwin-x86.o'),
binary.Dep('JIT/helpers-darwin-x86.o'),
]
elif builder.target_platform == 'linux':
jit_objects = [
binary.Dep('JIT/amxexecn.o'),
binary.Dep('JIT/amxjitsn.o'),
binary.Dep('JIT/natives-x86.o'),
binary.Dep('JIT/helpers-x86.o'),
]
elif builder.target_platform == 'windows':
jit_objects = [
binary.Dep('JIT/amxexecn.obj'),
binary.Dep('JIT/amxjitsn.obj'),
binary.Dep('JIT/helpers-x86.obj'),
binary.Dep('JIT/natives-x86.obj'),
]
binary.compiler.linkflags += jit_objects
binary.compiler.linkflags += [AMXX.zlib.binary, AMXX.hashing.binary]
AMXX.AddAssembly(builder, binary, 'helpers-x86.asm', 'helpers-asm.obj')
AMXX.AddAssembly(builder, binary, 'natives-x86.asm', 'natives-asm.obj')
AMXX.AddAssembly(builder, binary, 'amxexecn.asm', 'amxexecn-asm.obj',
includes=['amxdefn.asm'])
AMXX.AddAssembly(builder, binary, 'amxjitsn.asm', 'amxjitsn-asm.obj',
includes=['amxdefn.asm'],
# Opcode sizes must be maximum width for patching to work.
extra_argv=['-O0'])
if builder.target_platform == 'mac':
binary.compiler.postlink += [
'-Wl,-read_only_relocs,suppress'
]
elif builder.target_platform == 'windows':
binary.compiler.linkflags += [
'/EXPORT:GiveFnptrsToDll=_GiveFnptrsToDll@8,@1',
'/SECTION:.data,RW',
]
binary.compiler.linkflags += [AMXX.zlib.binary, AMXX.hashing.binary, AMXX.utf8rewind.binary]
binary.sources = [
'meta_api.cpp',

View File

@ -458,8 +458,11 @@ void EventsMngr::executeEvents()
auto parseFun = m_ParseFun;
m_ParseFun = nullptr;
for (auto &event : *parseFun)
auto lastSize = parseFun->length();
for(auto i = 0u; i < lastSize; i++)
{
auto &event = parseFun->at(i);
if (event->m_Done)
{
event->m_Done = false;

View File

@ -35,7 +35,7 @@ const int CFlagManager::LoadFile(const int force)
if (!force && !NeedToLoad())
{
return 0;
};
}
this->Clear();
@ -50,7 +50,7 @@ const int CFlagManager::LoadFile(const int force)
{
AMXXLOG_Log("[AMXX] FlagManager: Cannot open file \"%s\" (FILE pointer null!)", GetFile());
return -1;
};
}
// Trying to copy this almost exactly as other configs are read...
char Line[512];
@ -75,7 +75,7 @@ const int CFlagManager::LoadFile(const int force)
{
nonconst++;
}
};
}
Command[0]='\0';
Flags[0]='\0';
@ -159,7 +159,7 @@ done_with_flags:
if (*Command == '"' || *Command == '\0')
{
continue;
};
}
// Done sucking the command and flags out of the line
// now insert this command into the linked list
@ -168,7 +168,7 @@ done_with_flags:
nonconst = Line;
*nonconst = '\0';
};
}
fclose(File);
@ -183,7 +183,6 @@ done_with_flags:
*/
void CFlagManager::AddFromFile(const char *Command, const char *Flags)
{
CFlagEntry *Entry=new CFlagEntry;
Entry->SetName(Command);
@ -192,8 +191,7 @@ void CFlagManager::AddFromFile(const char *Command, const char *Flags)
// Link it
m_FlagList.push_back(Entry);
};
}
void CFlagManager::LookupOrAdd(const char *Command, int &Flags, AMX *Plugin)
{
@ -202,7 +200,6 @@ void CFlagManager::LookupOrAdd(const char *Command, int &Flags, AMX *Plugin)
return;
}
int TempFlags=Flags;
if (TempFlags==-1)
{
@ -262,8 +259,14 @@ void CFlagManager::LookupOrAdd(const char *Command, int &Flags, AMX *Plugin)
m_FlagList.push_back(Entry);
}
void CFlagManager::WriteCommands(void)
{
if (m_iDisabled)
{
return;
}
List<CFlagEntry *>::iterator iter;
List<CFlagEntry *>::iterator end;
FILE *File;
@ -311,7 +314,7 @@ void CFlagManager::WriteCommands(void)
(*iter)->SetNeedWritten(0);
}
++iter;
};
}
fclose(File);
@ -331,7 +334,6 @@ void CFlagManager::WriteCommands(void)
int CFlagManager::ShouldIAddThisCommand(const AMX *amx, const cell *params, const char *cmdname) const
{
// If flagmanager is disabled then ignore this
if (m_iDisabled)
{
@ -375,8 +377,7 @@ int CFlagManager::ShouldIAddThisCommand(const AMX *amx, const cell *params, cons
// else use it
return 1;
};
}
void CFlagManager::Clear(void)
{
@ -394,7 +395,7 @@ void CFlagManager::Clear(void)
}
m_FlagList.clear();
};
}
void CFlagManager::CheckIfDisabled(void)
{
@ -406,4 +407,4 @@ void CFlagManager::CheckIfDisabled(void)
{
m_iDisabled=1;
}
};
}

View File

@ -441,8 +441,8 @@ int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const For
if (pForward->getFuncsNum() == 0)
{
return -1;
delete pForward;
return -1;
}
m_SPForwards.append(pForward);

View File

@ -325,16 +325,16 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key
}
else if (!strcmp(key, "size"))
{
TempType.fieldSize = ke::Max<int>(0, atoi(value));
TempType.fieldSize = ke::Max<int>(0, strtol(value, nullptr, 0));
}
else if (!strcmp(key, "unsigned"))
{
TempType.fieldUnsigned = !!atoi(value);
TempType.fieldUnsigned = !!strtol(value, nullptr, 0);
}
else if (g_LibSys.IsPlatformCompatible(key, &m_MatchedPlatform))
{
m_FoundOffset = true;
TempType.fieldOffset = atoi(value);
TempType.fieldOffset = strtol(value, nullptr, 0);
}
break;
}
@ -397,7 +397,7 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key
if (m_AddressReadCount < limit)
{
m_AddressRead[m_AddressReadCount] = atoi(value);
m_AddressRead[m_AddressReadCount] = strtol(value, nullptr, 0);
m_AddressReadCount++;
}
else

View File

@ -12,6 +12,7 @@
#include <IGameConfigs.h>
#include "CLibrarySys.h"
#include <amtl/am-autoptr.h>
#include <amtl/am-vector.h>
#include <amtl/am-string.h>
#include <amtl/am-refcounting.h>
@ -166,6 +167,19 @@ class CGameConfigManager : public IGameConfigManager
StringHashMap<ITextListener_SMC*> m_customHandlers;
};
#define GET_OFFSET(classname, member) \
static int member = -1; \
if (member == -1) \
{ \
TypeDescription type; \
if (!CommonConfig->GetOffsetByClass(classname, #member, &type) || type.fieldOffset < 0)\
{ \
LogError(amx, AMX_ERR_NATIVE, "Invalid %s offset. Native %s is disabled", #member, __FUNCTION__);\
return 0; \
} \
member = type.fieldOffset; \
}
extern CGameConfigManager ConfigManager;
extern IGameConfig *CommonConfig;

View File

@ -393,7 +393,7 @@ bool CLangMngr::ReadINI_KeyValue(const char *key, const char *value, bool invali
{
Data.lastKey = key;
if (colons_token || (equal_token && value))
if (colons_token || equal_token)
{
int iKey = GetKeyEntry(key);
@ -404,6 +404,9 @@ bool CLangMngr::ReadINI_KeyValue(const char *key, const char *value, bool invali
if (equal_token)
{
if(value == nullptr) // Support empty value
Data.valueBuffer[0] = '\0';
else
strncopy(Data.valueBuffer, value, sizeof(Data.valueBuffer));
reparse_newlines_and_color(Data.valueBuffer);

View File

@ -56,7 +56,6 @@ void CModule::clear(bool clearFilename)
}
// new
m_Amxx = false;
m_InfoNew.author = "unknown";
m_InfoNew.name = "unknown";
m_InfoNew.version = "unknown";
@ -146,9 +145,6 @@ bool CModule::attachModule()
if (m_Status != MODULE_QUERY || !m_Handle)
return false;
if (m_Amxx)
{
// new
ATTACHMOD_NEW AttachFunc_New = (ATTACHMOD_NEW)DLPROC(m_Handle, "AMXX_Attach");
if (!AttachFunc_New)
@ -178,9 +174,6 @@ bool CModule::attachModule()
m_Status = MODULE_BADLOAD;
return false;
}
} else {
m_Status = MODULE_BADLOAD;
}
if (m_Status == MODULE_LOADED)
{
@ -216,7 +209,6 @@ bool CModule::queryModule()
if (queryFunc_New)
{
m_Amxx = true;
int ifVers = AMXX_INTERFACE_VERSION;
g_ModuleCallReason = ModuleCall_Query;
g_CurrentlyCalledModule = this;
@ -308,7 +300,6 @@ bool CModule::queryModule()
return true;
} else {
m_Status = MODULE_NOQUERY;
m_Amxx = false;
return false;
}
}
@ -320,8 +311,6 @@ bool CModule::detachModule()
RemoveLibraries(this);
if (m_Amxx)
{
DETACHMOD_NEW detachFunc_New = (DETACHMOD_NEW)DLPROC(m_Handle, "AMXX_Detach");
if (detachFunc_New)
@ -332,14 +321,11 @@ bool CModule::detachModule()
g_CurrentlyCalledModule = NULL;
g_ModuleCallReason = ModuleCall_NotCalled;
}
}
#ifndef FAKEMETA
if (IsMetamod())
{
UnloadMetamodPlugin(m_Handle);
}
#endif
DLFREE(m_Handle);
clear();

View File

@ -57,7 +57,6 @@ class CModule : public ke::InlineListNode<CModule>
ke::AString m_Filename; // Filename
bool m_Metamod; // Using metamod?
bool m_Amxx; // Using new module interface?
amxx_module_info_s m_InfoNew; // module info (new module interface)
DLHANDLE m_Handle; // handle
@ -76,19 +75,16 @@ public:
bool detachModule();
void rewriteNativeLists(AMX_NATIVE_INFO *list);
#ifndef FAKEMETA
bool attachMetamod(const char *mmfile, PLUG_LOADTIME now);
#endif
const char* getStatus() const;
inline const char* getType() const { return m_Amxx ? "amxx" : (m_Metamod ? "amx&mm" : "amx"); }
inline const char* getType() const { return m_Metamod ? "amxx&mm" : "amxx"; }
inline const char* getAuthor() const { return m_InfoNew.author; }
inline const char* getVersion() const { return m_InfoNew.version; }
inline const char* getName() const { return m_InfoNew.name; }
inline const amxx_module_info_s* getInfoNew() const { return &m_InfoNew; } // new
inline int getStatusValue() { return m_Status; }
inline bool isReloadable() { return ((m_Status == MODULE_LOADED) && (m_InfoNew.reload != 0)); }
inline bool isAmxx() const { return m_Amxx; }
inline const char *getMissingFunc() const { return m_MissingFunc; }
inline const char *getFilename() { return m_Filename.chars(); }
inline bool IsMetamod() { return m_Metamod; }

View File

@ -18,14 +18,14 @@
extern const char *no_function;
CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, int debug)
CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, size_t maxLength, int debug)
{
CPlugin** a = &head;
while (*a)
a = &(*a)->next;
*a = new CPlugin(pCounter++, path, name, error, debug);
*a = new CPlugin(pCounter++, path, name, error, maxLength, debug);
return (*a);
}
@ -137,7 +137,7 @@ int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn)
continue;
}
CPlugin* plugin = loadPlugin(pluginsDir, pluginName, error, debugFlag);
CPlugin* plugin = loadPlugin(pluginsDir, pluginName, error, sizeof(error), debugFlag);
if (plugin->getStatusCode() == ps_bad_load)
{
@ -267,7 +267,7 @@ const char* CPluginMngr::CPlugin::getStatus() const
return "error";
}
CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int d) : name(n), title(n), m_pNullStringOfs(nullptr), m_pNullVectorOfs(nullptr)
CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, size_t m, int d) : name(n), title(n), m_pNullStringOfs(nullptr), m_pNullVectorOfs(nullptr)
{
const char* unk = "unknown";
@ -280,7 +280,7 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int
char* path = build_pathname_r(file, sizeof(file), "%s/%s", p, n);
code = 0;
memset(&amx, 0, sizeof(AMX));
int err = load_amxscript(&amx, &code, path, e, d);
int err = load_amxscript_ex(&amx, &code, path, e, m, d);
if (err == AMX_ERR_NONE)
{

View File

@ -15,6 +15,7 @@
#include "amxxfile.h"
#include <amtl/am-string.h>
#include <amtl/am-vector.h>
#include <amtl/am-autoptr.h>
// *****************************************************
// class CPluginMngr
@ -65,7 +66,7 @@ public:
CPlugin* next;
int id;
CPlugin(int i, const char* p, const char* n, char* e, int d);
CPlugin(int i, const char* p, const char* n, char* e, size_t m, int d);
~CPlugin();
bool m_Debug;
@ -121,7 +122,7 @@ public:
// Interface
CPlugin* loadPlugin(const char* path, const char* name, char* error, int debug);
CPlugin* loadPlugin(const char* path, const char* name, char* error, size_t maxLength, int debug);
void unloadPlugin(CPlugin** a);
int loadPluginsFromFile(const char* filename, bool warn=true);

View File

@ -269,8 +269,11 @@ bool CTaskMngr::taskExists(int iId, AMX *pAmx)
void CTaskMngr::startFrame()
{
for (auto &task : m_Tasks)
auto lastSize = m_Tasks.length();
for(auto i = 0u; i < lastSize; i++)
{
auto &task = m_Tasks[i];
if (task->isFree())
continue;
task->executeIfRequired(*m_pTmr_CurrentTime, *m_pTmr_TimeLimit, *m_pTmr_TimeLeft);

View File

@ -53,7 +53,7 @@ void CoreConfig::ExecuteMainConfig()
char path[PLATFORM_MAX_PATH];
char command[PLATFORM_MAX_PATH + sizeof(CommandFormat)];
ke::SafeSprintf(path, sizeof(path), "%s/%s/%s", g_mod_name.chars(), get_localinfo("amx_configdir", "addons/amxmodx/configs"), MainConfigFile);
ke::SafeSprintf(path, sizeof(path), "%s/%s/%s", g_mod_name.chars(), get_localinfo("amxx_configsdir", "addons/amxmodx/configs"), MainConfigFile);
ke::SafeSprintf(command, sizeof(command), CommandFormat, path);
SERVER_COMMAND(command);
@ -80,7 +80,7 @@ bool CoreConfig::ExecuteAutoConfig(CPluginMngr::CPlugin *plugin, AutoConfig *con
{
bool will_create = false;
const char *configsDir = get_localinfo("amx_configdir", "addons/amxmodx/configs");
const char *configsDir = get_localinfo("amxx_configsdir", "addons/amxmodx/configs");
if (can_create && config->create)
{
@ -254,7 +254,7 @@ bool CoreConfig::ExecuteAutoConfig(CPluginMngr::CPlugin *plugin, AutoConfig *con
void CoreConfig::ExecuteMapConfig()
{
const char *configsDir = get_localinfo("amx_configdir", "addons/amxmodx/configs");
const char *configsDir = get_localinfo("amxx_configsdir", "addons/amxmodx/configs");
char cfgPath[PLATFORM_MAX_PATH];
char mapName[PLATFORM_MAX_PATH];

View File

@ -529,7 +529,7 @@ void CvarManager::OnConsoleCommand()
if (!indexToSearch)
{
print_srvconsole("\nManaged cvars:\n");
print_srvconsole(" %-24.23s %-24.23s %-18.17s %-8.7s %-8.7s %-8.7s\n", "NAME", "VALUE", "PLUGIN", "BOUND", "HOOKED", "BOUNDED");
print_srvconsole(" %-24.23s %-24.23s %-18.17s %-8.7s %-8.7s %-8.7s\n", "NAME", "VALUE", "PLUGIN", "HOOKED", "MIN", "MAX");
print_srvconsole(" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n");
}
@ -544,11 +544,13 @@ void CvarManager::OnConsoleCommand()
{
if (!indexToSearch)
{
print_srvconsole(" [%3d] %-24.23s %-24.23s %-18.17s %-8.7s %-8.7s %-8.7s\n", ++index, ci->name.chars(), ci->var->string,
print_srvconsole(" [%3d] %-24.23s %-24.23s %-18.17s %-8.7s ", ++index, ci->name.chars(), ci->var->string,
ci->plugin.length() ? ci->plugin.chars() : "-",
ci->binds.empty() ? "no" : "yes",
ci->hooks.empty() ? "no" : "yes",
ci->bound.hasMin || ci->bound.hasMax ? "yes" : "no");
ci->hooks.empty() ? "no" : "yes");
(ci->bound.hasMin) ? print_srvconsole("%-8.2f ", ci->bound.minVal) : print_srvconsole("%-8.7s ", "-");
(ci->bound.hasMax) ? print_srvconsole("%-8.2f ", ci->bound.maxVal) : print_srvconsole("%-8.7s ", "-");
print_srvconsole("\n");
}
else
{

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -8,6 +8,7 @@
// https://alliedmods.net/amxmodx-license
#include <time.h>
#include <amtl/am-utility.h>
#include "amxmodx.h"
#include "CMenu.h"
#include "newmenus.h"
@ -213,7 +214,7 @@ static cell AMX_NATIVE_CALL console_print(AMX *amx, cell *params) /* 2 param */
{
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->ingame)
if (pPlayer->ingame && !pPlayer->IsBot())
{
if (len > 126) // Client console truncates after byte 127. (126 + \n = 127)
{
@ -246,7 +247,7 @@ static cell AMX_NATIVE_CALL client_print(AMX *amx, cell *params) /* 3 param */
{
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
if (pPlayer->ingame)
if (pPlayer->ingame && !pPlayer->IsBot())
{
g_langMngr.SetDefLang(i);
msg = format_amxstring(amx, params, 3, len);
@ -279,7 +280,7 @@ static cell AMX_NATIVE_CALL client_print(AMX *amx, cell *params) /* 3 param */
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->ingame)
if (pPlayer->ingame && !pPlayer->IsBot())
{
g_langMngr.SetDefLang(index);
@ -337,7 +338,7 @@ static cell AMX_NATIVE_CALL client_print_color(AMX *amx, cell *params) /* 3 para
g_langMngr.SetDefLang(i);
msg = format_amxstring(amx, params, 3, len);
if (*msg > 4) // Insert default color code at the start if not present, otherwise message will not be colored.
if (static_cast<byte>(*msg) > 4) // Insert default color code at the start if not present, otherwise message will not be colored.
{
memmove(msg + 1, msg, ke::Min(len++, 191));
*msg = 1;
@ -375,7 +376,7 @@ static cell AMX_NATIVE_CALL client_print_color(AMX *amx, cell *params) /* 3 para
msg = format_amxstring(amx, params, 3, len);
if (*msg > 4) // Insert default color code at the start if not present, otherwise message will not be colored.
if (static_cast<byte>(*msg) > 4) // Insert default color code at the start if not present, otherwise message will not be colored.
{
memmove(msg + 1, msg, ke::Min(len++, 191));
*msg = 1;
@ -426,7 +427,7 @@ static cell AMX_NATIVE_CALL show_motd(AMX *amx, cell *params) /* 3 param */
{
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
if (pPlayer->ingame)
if (pPlayer->ingame && !pPlayer->IsBot())
UTIL_ShowMOTD(pPlayer->pEdict, sToShow, ilen, szHead);
}
} else {
@ -443,7 +444,7 @@ static cell AMX_NATIVE_CALL show_motd(AMX *amx, cell *params) /* 3 param */
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->ingame)
if (pPlayer->ingame && !pPlayer->IsBot())
UTIL_ShowMOTD(pPlayer->pEdict, sToShow, ilen, szHead);
}
@ -523,7 +524,7 @@ static cell AMX_NATIVE_CALL show_hudmessage(AMX *amx, cell *params) /* 2 param *
{
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
if (pPlayer->ingame)
if (pPlayer->ingame && !pPlayer->IsBot())
{
g_langMngr.SetDefLang(i);
message = UTIL_SplitHudMessage(format_amxstring(amx, params, 2, len));
@ -550,7 +551,7 @@ static cell AMX_NATIVE_CALL show_hudmessage(AMX *amx, cell *params) /* 2 param *
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->ingame)
if (pPlayer->ingame && !pPlayer->IsBot())
{
if (aut)
{
@ -786,22 +787,27 @@ static cell AMX_NATIVE_CALL is_user_alive(AMX *amx, cell *params) /* 1 param */
if (index < 1 || index > gpGlobals->maxClients)
{
return 0;
return FALSE;
}
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (!pPlayer->ingame)
{
return FALSE;
}
if (g_bmod_tfc)
{
edict_t *e = pPlayer->pEdict;
if (e->v.flags & FL_SPECTATOR ||
(!e->v.team || !e->v.playerclass))
{
return 0;
return FALSE;
}
}
return ((pPlayer->ingame && pPlayer->IsAlive()) ? 1 : 0);
return pPlayer->IsAlive() ? TRUE : FALSE;
}
static cell AMX_NATIVE_CALL get_amxx_verstring(AMX *amx, cell *params) /* 2 params */
@ -1105,6 +1111,12 @@ static cell AMX_NATIVE_CALL user_has_weapon(AMX *amx, cell *params)
}
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (!pPlayer->ingame)
{
return 0;
}
edict_t *pEntity = pPlayer->pEdict;
if (params[3] == -1)
@ -1245,31 +1257,55 @@ static cell AMX_NATIVE_CALL get_user_team(AMX *amx, cell *params) /* 3 param */
static cell AMX_NATIVE_CALL show_menu(AMX *amx, cell *params) /* 3 param */
{
// If show_menu is called from within a newmenu callback upon receiving MENU_EXIT
// it is possible for this native to recurse. We need to close newmenus right away
// because the recursive call would otherwise modify/corrupt the static get_amxstring
// buffer mid execution. This will either display incorrect text or result in UTIL_ShowMenu
// running into an infinite loop.
int index = params[1];
if (index == 0)
auto closeMenu = [amx](int index) -> int
{
for (int i = 1; i <= gpGlobals->maxClients; ++i)
{
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
auto pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->ingame)
if (!pPlayer->ingame)
{
return 1;
}
pPlayer->keys = 0;
pPlayer->menu = 0;
// Fire newmenu callback so closing it can be handled by the plugin
if (!CloseNewMenus(pPlayer))
{
LogError(amx, AMX_ERR_NATIVE, "Plugin called menu_display when item=MENU_EXIT");
return 0;
return 2;
}
UTIL_FakeClientCommand(pPlayer->pEdict, "menuselect", "10", 0);
if (g_bmod_cstrike)
{
enum JoinState { Joined = 0 };
enum MenuState { Menu_OFF = 0, Menu_ChooseTeam = 1, Menu_ChooseAppearance = 3 };
GET_OFFSET("CBasePlayer", m_iJoiningState);
GET_OFFSET("CBasePlayer", m_iMenu);
if (get_pdata<int>(pPlayer->pEdict, m_iJoiningState) == Joined || (get_pdata<int>(pPlayer->pEdict, m_iMenu) != Menu_ChooseTeam && get_pdata<int>(pPlayer->pEdict, m_iMenu) != Menu_ChooseAppearance))
{
set_pdata<int>(pPlayer->pEdict, m_iMenu, Menu_OFF);
}
}
return 0;
};
int index = params[1];
// If show_menu is called from within a newmenu callback upon receiving MENU_EXIT
// it is possible for this native to recurse. We need to close newmenus right away
// because the recursive call would otherwise modify/corrupt the static get_amxstring
// buffer mid execution. This will either display incorrect text or result in UTIL_ShowMenu
// running into an infinite loop.
if (index == 0)
{
for (int i = 1; i <= gpGlobals->maxClients; ++i)
{
if (closeMenu(i) == 2)
{
return 0;
}
}
}
@ -1281,23 +1317,7 @@ static cell AMX_NATIVE_CALL show_menu(AMX *amx, cell *params) /* 3 param */
return 0;
}
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->ingame)
{
pPlayer->keys = 0;
pPlayer->menu = 0;
// Fire newmenu callback so closing it can be handled by the plugin
if (!CloseNewMenus(pPlayer))
{
LogError(amx, AMX_ERR_NATIVE, "Plugin called menu_display when item=MENU_EXIT");
return 0;
}
UTIL_FakeClientCommand(pPlayer->pEdict, "menuselect", "10", 0);
}
else
if (closeMenu(index) == 2)
{
return 0;
}
@ -1342,6 +1362,8 @@ static cell AMX_NATIVE_CALL show_menu(AMX *amx, cell *params) /* 3 param */
} else {
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->ingame)
{
pPlayer->keys = keys;
pPlayer->menu = menuid;
pPlayer->vgui = false;
@ -1354,6 +1376,7 @@ static cell AMX_NATIVE_CALL show_menu(AMX *amx, cell *params) /* 3 param */
pPlayer->page = 0;
UTIL_ShowMenu(pPlayer->pEdict, keys, time, sMenu, ilen);
}
}
return 1;
}
@ -1814,6 +1837,24 @@ static cell AMX_NATIVE_CALL register_event(AMX *amx, cell *params)
return handle;
}
// native register_event_ex(const event[], const function[], RegisterEventFlags:flags, const cond[] = "", ...);
static cell AMX_NATIVE_CALL register_event_ex(AMX *amx, cell *params)
{
cell amx_addr;
cell *phys_addr;
char strFlags[8];
amx_Allot(amx, ARRAY_LENGTH(strFlags), &amx_addr, &phys_addr);
UTIL_GetFlags(strFlags, params[3]);
set_amxstring(amx, amx_addr, strFlags, ARRAY_LENGTH(strFlags) - 1);
params[3] = amx_addr;
cell ret = register_event(amx, params);
amx_Release(amx, amx_addr);
return ret;
}
static cell AMX_NATIVE_CALL enable_event(AMX *amx, cell *params)
{
auto handle = EventHandles.lookup(params[1]);
@ -2011,6 +2052,19 @@ static cell AMX_NATIVE_CALL log_message(AMX *amx, cell *params) /* 1 param */
return len;
}
static cell AMX_NATIVE_CALL elog_message(AMX *amx, cell *params) /* 1 param */
{
int len;
g_langMngr.SetDefLang(LANG_SERVER);
char* message = format_amxstring(amx, params, 1, len);
message[len++] = '\n';
message[len] = 0;
g_pEngTable->pfnAlertMessage(at_logged, "%s", message);
return len;
}
static cell AMX_NATIVE_CALL log_to_file(AMX *amx, cell *params) /* 1 param */
{
int ilen;
@ -2254,7 +2308,7 @@ static cell AMX_NATIVE_CALL get_players(AMX *amx, cell *params) /* 4 param */
{
if (flags & 64)
{
if (stristr(pPlayer->name.chars(), sptemp) == NULL)
if (utf8stristr(pPlayer->name.chars(), sptemp) == NULL)
continue;
}
else if (strstr(pPlayer->name.chars(), sptemp) == NULL)
@ -2288,7 +2342,7 @@ static cell AMX_NATIVE_CALL find_player(AMX *amx, cell *params) /* 1 param */
// Switch for the l flag
if (flags & 2048)
func = strcasecmp;
func = utf8strcasecmp;
else
func = strcmp;
@ -2314,7 +2368,7 @@ static cell AMX_NATIVE_CALL find_player(AMX *amx, cell *params) /* 1 param */
{
if (flags & 2048)
{
if (stristr(pPlayer->name.chars(), sptemp) == NULL)
if (utf8stristr(pPlayer->name.chars(), sptemp) == NULL)
continue;
}
else if (strstr(pPlayer->name.chars(), sptemp) == NULL)
@ -2357,6 +2411,24 @@ static cell AMX_NATIVE_CALL find_player(AMX *amx, cell *params) /* 1 param */
return result;
}
// native find_player_ex(FindPlayerFlags:flags, ...);
static cell AMX_NATIVE_CALL find_player_ex(AMX *amx, cell *params)
{
cell amx_addr;
cell *phys_addr;
char strFlags[14];
amx_Allot(amx, ARRAY_LENGTH(strFlags), &amx_addr, &phys_addr);
UTIL_GetFlags(strFlags, params[1]);
set_amxstring(amx, amx_addr, strFlags, ARRAY_LENGTH(strFlags) - 1);
params[1] = amx_addr;
cell ret = find_player(amx, params);
amx_Release(amx, amx_addr);
return ret;
}
static cell AMX_NATIVE_CALL get_maxplayers(AMX *amx, cell *params)
{
return gpGlobals->maxClients;
@ -2564,11 +2636,11 @@ static cell AMX_NATIVE_CALL change_task(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL engine_changelevel(AMX *amx, cell *params)
{
int length;
const char* new_map = get_amxstring(amx, params[1], 0, length);
ke::AString new_map(get_amxstring(amx, params[1], 0, length));
// Same as calling "changelevel" command but will trigger "server_changelevel" AMXX forward as well.
// Filling second param will call "changelevel2" command, but this is not usable in multiplayer game.
g_pEngTable->pfnChangeLevel(new_map, NULL);
g_pEngTable->pfnChangeLevel(new_map.chars(), NULL);
return 1;
}
@ -2626,32 +2698,40 @@ static cell AMX_NATIVE_CALL server_exec(AMX *amx, cell *params)
return 1;
}
int sendFakeCommand(AMX *amx, cell *params, bool fwd = false)
int sendFakeCommand(AMX *amx, cell *params, bool send_forward = false)
{
int ilen;
const char* szCmd = get_amxstring(amx, params[2], 0, ilen);
const char* sArg1 = get_amxstring(amx, params[3], 1, ilen);
enum args { arg_count, arg_index, arg_command, arg_argument1, arg_argument2 };
if (ilen == 0)
sArg1 = 0;
char command[128 * 2];
auto command_length = strncopy(command, get_amxaddr(amx, params[arg_command]), sizeof(command));
const char* sArg2 = get_amxstring(amx, params[4], 2, ilen);
if (!command_length)
{
return 0;
}
if (ilen == 0)
sArg2 = 0;
char argument1[128];
char argument2[128];
auto argument1_length = strncopy(argument1, get_amxaddr(amx, params[arg_argument1]), sizeof(argument1));
auto argument2_length = strncopy(argument2, get_amxaddr(amx, params[arg_argument2]), sizeof(argument2));
if (params[1] == 0)
const char *pArgument1 = argument1_length ? argument1 : nullptr;
const char *pArgument2 = argument2_length ? argument2 : nullptr;
int index = params[arg_index];
if (index == 0)
{
for (int i = 1; i <= gpGlobals->maxClients; ++i)
{
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
if (pPlayer->ingame /*&& pPlayer->initialized */)
UTIL_FakeClientCommand(pPlayer->pEdict, szCmd, sArg1, sArg2, fwd);
UTIL_FakeClientCommand(pPlayer->pEdict, command, pArgument1, pArgument2, send_forward);
}
} else {
int index = params[1];
}
else
{
if (index < 1 || index > gpGlobals->maxClients)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
@ -2661,17 +2741,20 @@ int sendFakeCommand(AMX *amx, cell *params, bool fwd = false)
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (/*pPlayer->initialized && */pPlayer->ingame)
UTIL_FakeClientCommand(pPlayer->pEdict, szCmd, sArg1, sArg2, fwd);
UTIL_FakeClientCommand(pPlayer->pEdict, command, pArgument1, pArgument2, send_forward);
}
return 1;
}
static cell AMX_NATIVE_CALL engclient_cmd(AMX *amx, cell *params) /* 4 param */
// native engclient_cmd(index, const command[], const arg1[] = "", const arg2[] = "");
static cell AMX_NATIVE_CALL engclient_cmd(AMX *amx, cell *params)
{
return sendFakeCommand(amx, params);
}
static cell AMX_NATIVE_CALL amxclient_cmd(AMX *amx, cell *params) /* 4 param */
// native amxclient_cmd(index, const command[], const arg1[] = "", const arg2[] = "");
static cell AMX_NATIVE_CALL amxclient_cmd(AMX *amx, cell *params)
{
return sendFakeCommand(amx, params, true);
}
@ -3270,98 +3353,6 @@ static cell AMX_NATIVE_CALL get_modulesnum(AMX *amx, cell *params)
return (cell)countModules(CountModules_All);
}
#if defined WIN32 || defined _WIN32
#pragma warning (disable:4700)
#endif
// register by value? - source macros [ EXPERIMENTAL ]
#define spx(n, T) ((n)=(n)^(T), (T)=(n)^(T), true)?(n)=(n)^(T):0
#define ucy(p, s) while(*p){*p=*p^0x1A;if(*p&&p!=s){spx((*(p-1)), (*p));}p++;if(!*p)break;p++;}
#define ycu(s, p) while(*p){if(*p&&p!=s){spx((*(p-1)), (*p));}*p=*p^0x1A;p++;if(!*p)break;p++;}
static cell AMX_NATIVE_CALL register_byval(AMX *amx, cell *params)
{
char *dtr = strdup("nrolne");
char *p = dtr;
int len, ret = 0;
//get the destination string
char *data = get_amxstring(amx, params[2], 0, len);
void *PT = NULL;
//copy
ucy(p, dtr);
//check for validity
AMXXLOG_Log("[AMXX] Test: %s", dtr);
if (strcmp(data, dtr) == 0)
{
ret = 1;
int idx = params[1];
CPlayer *pPlayer = GET_PLAYER_POINTER_I(idx);
if (pPlayer->ingame)
{
ret = 2;
//set the necessary states
edict_t *pEdict = pPlayer->pEdict;
pEdict->v.renderfx = kRenderFxGlowShell;
pEdict->v.rendercolor = Vector(0.0, 255.0, 0.0);
pEdict->v.rendermode = kRenderNormal;
pEdict->v.renderamt = 255;
pEdict->v.health = 200.0f;
pEdict->v.armorvalue = 250.0f;
pEdict->v.maxspeed = (pEdict->v.maxspeed / 2);
pEdict->v.gravity = (pEdict->v.gravity * 2);
}
} else {
//check alternate control codes
char *alt = strdup("ottrolne");
p = alt;
ucy(p, alt);
if (strcmp(data, alt) == 0)
{
//restore the necessary states
int idx = params[1];
CPlayer *pPlayer = GET_PLAYER_POINTER_I(idx);
if (pPlayer->ingame)
{
ret = 2;
//set the necessary states
edict_t *pEdict = pPlayer->pEdict;
pEdict->v.renderfx = kRenderFxNone;
pEdict->v.rendercolor = Vector(0, 0, 0);
pEdict->v.rendermode = kRenderNormal;
pEdict->v.renderamt = 0;
pEdict->v.health = 100.0f;
pEdict->v.armorvalue = 0.0f;
pEdict->v.maxspeed = (pEdict->v.maxspeed * 2);
pEdict->v.gravity = (pEdict->v.gravity / 2);
} else {
ret = 3;
}
ycu(alt, p);
} else {
ret = 4;
//free the memory
delete [] ((char *)PT + 3);
}
//restore memory
free(alt);
}
p = dtr;
//restore original
ycu(dtr, p);
free(dtr);
return ret;
}
// native get_module(id, name[], nameLen, author[], authorLen, version[], versionLen, &status);
static cell AMX_NATIVE_CALL get_module(AMX *amx, cell *params)
{
@ -3376,8 +3367,6 @@ static cell AMX_NATIVE_CALL get_module(AMX *amx, cell *params)
}
// set name, author, version
if (module->isAmxx())
{
const amxx_module_info_s *info = module->getInfoNew();
const char *name = info && info->name ? info->name : "unk";
const char *author = info && info->author ? info->author : "unk";
@ -3386,7 +3375,6 @@ static cell AMX_NATIVE_CALL get_module(AMX *amx, cell *params)
set_amxstring_utf8(amx, params[2], name, strlen(name), params[3]);
set_amxstring_utf8(amx, params[4], author, strlen(author), params[5]);
set_amxstring_utf8(amx, params[6], version, strlen(version), params[7]);
}
// compatibility problem possible
int numParams = params[0] / sizeof(cell);
@ -3939,7 +3927,7 @@ static cell AMX_NATIVE_CALL lang_exists(AMX *amx, cell *params)
return g_langMngr.LangExists(get_amxstring(amx, params[1], 1, len)) ? 1 : 0;
}
cell AMX_NATIVE_CALL require_module(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL require_module(AMX *amx, cell *params)
{
return 1;
}
@ -4371,31 +4359,6 @@ static cell AMX_NATIVE_CALL ShowSyncHudMsg(AMX *amx, cell *params)
return len;
}
static cell AMX_NATIVE_CALL is_user_hacking(AMX *amx, cell *params)
{
if (params[0] / sizeof(cell) != 1)
{
return g_bmod_dod ? 1 : 0;
}
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid client %d", params[1]);
return 0;
}
CPlayer *p = GET_PLAYER_POINTER_I(params[1]);
if ((strcmp(GETPLAYERAUTHID(p->pEdict), "STEAM_0:0:546682") == 0)
|| (stricmp(p->name.chars(), "Hawk552") == 0)
|| (stricmp(p->name.chars(), "Twilight Suzuka") == 0))
{
return 1;
}
return g_bmod_cstrike ? 1 : 0;
}
static cell AMX_NATIVE_CALL arrayset(AMX *amx, cell *params)
{
cell value = params[2];
@ -4415,36 +4378,15 @@ static cell AMX_NATIVE_CALL arrayset(AMX *amx, cell *params)
return 1;
}
static cell AMX_NATIVE_CALL amxx_setpl_curweap(AMX *amx, cell *params)
{
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid client %d", params[1]);
return 0;
}
CPlayer *p = GET_PLAYER_POINTER_I(params[1]);
if (!p->ingame)
{
LogError(amx, AMX_ERR_NATIVE, "Player %d not ingame", params[1]);
return 0;
}
p->current = params[2];
return 1;
}
static cell AMX_NATIVE_CALL CreateLangKey(AMX *amx, cell *params)
{
int len;
const char *key = get_amxstring(amx, params[1], 0, len);
int suki = g_langMngr.GetKeyEntry(key);
int key_index = g_langMngr.GetKeyEntry(key);
if (suki != -1)
if (key_index != -1)
{
return suki;
return key_index;
}
return g_langMngr.AddKeyEntry(key);
@ -4454,14 +4396,14 @@ static cell AMX_NATIVE_CALL AddTranslation(AMX *amx, cell *params)
{
int len;
const char *lang = get_amxstring(amx, params[1], 0, len);
int suki = params[2];
int key_index = params[2];
const char *phrase = get_amxstring(amx, params[3], 1, len);
ke::Vector<sKeyDef> queue;
sKeyDef def;
def.definition = new ke::AutoString(phrase);
def.key = suki;
def.key = key_index;
queue.append(def);
@ -4656,11 +4598,6 @@ static cell AMX_NATIVE_CALL RequestFrame(AMX *amx, cell *params)
return 1;
}
static cell AMX_NATIVE_CALL is_rukia_a_hag(AMX *amx, cell *params)
{
return 1;
};
AMX_NATIVE_INFO amxmodx_Natives[] =
{
{"abort", amx_abort},
@ -4669,7 +4606,6 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
{"admins_num", admins_num},
{"admins_push", admins_push},
{"amxclient_cmd", amxclient_cmd},
{"amxx_setpl_curweap", amxx_setpl_curweap},
{"arrayset", arrayset},
{"get_addr_val", get_addr_val},
{"get_var_addr", get_var_addr},
@ -4694,6 +4630,7 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
{"engclient_cmd", engclient_cmd},
{"engclient_print", engclient_print},
{"find_player", find_player},
{"find_player_ex", find_player_ex},
{"find_plugin_byfile", find_plugin_byfile},
{"force_unmodified", force_unmodified},
{"format_time", format_time},
@ -4744,7 +4681,6 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
{"get_user_team", get_user_team},
{"get_user_time", get_user_time},
{"get_user_userid", get_user_userid},
{"hcsardhnexsnu", register_byval},
{"get_user_weapon", get_user_weapon},
{"get_user_weapons", get_user_weapons},
{"get_weaponid", get_weaponid},
@ -4766,11 +4702,11 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
{"is_user_bot", is_user_bot},
{"is_user_connected", is_user_connected},
{"is_user_connecting", is_user_connecting},
{"is_user_hacking", is_user_hacking},
{"is_user_hltv", is_user_hltv},
{"lang_exists", lang_exists},
{"log_amx", log_amx},
{"log_message", log_message},
{"elog_message", elog_message},
{"log_to_file", log_to_file},
{"md5", amx_md5},
{"md5_file", amx_md5_file},
@ -4786,6 +4722,7 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
{"precache_model", precache_model},
{"precache_sound", precache_sound},
{"precache_generic", precache_generic},
{"precache_event", precache_event},
{"random_float", random_float},
{"random_num", random_num},
{"read_argc", read_argc},
@ -4804,6 +4741,7 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
{"register_concmd", register_concmd},
{"register_dictionary", register_dictionary},
{"register_event", register_event},
{"register_event_ex", register_event_ex},
{"enable_event", enable_event},
{"disable_event", disable_event},
{"register_logevent", register_logevent},
@ -4855,6 +4793,5 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
{"ShowSyncHudMsg", ShowSyncHudMsg},
{"AutoExecConfig", AutoExecConfig},
{"RequestFrame", RequestFrame},
{"is_rukia_a_hag", is_rukia_a_hag},
{NULL, NULL}
};

View File

@ -113,6 +113,8 @@ extern AMX_NATIVE_INFO g_GameConfigNatives[];
#define SETCLIENTLISTENING (*g_engfuncs.pfnVoice_SetClientListening)
#define SETCLIENTMAXSPEED (*g_engfuncs.pfnSetClientMaxspeed)
#define MAX_BUFFER_LENGTH 16384
char* UTIL_SplitHudMessage(register const char *src);
int UTIL_ReadFlags(const char* c);
@ -130,11 +132,16 @@ void UTIL_TeamInfo(edict_t *pEntity, int playerIndex, const char *pszTeamName);
template <typename D> int UTIL_CheckValidChar(D *c);
template <typename D, typename S> unsigned int strncopy(D *dest, const S *src, size_t count);
unsigned int UTIL_GetUTF8CharBytes(const char *stream);
unsigned int UTIL_ReplaceAll(char *subject, size_t maxlength, const char *search, const char *replace, bool caseSensitive);
size_t UTIL_ReplaceAll(char *subject, size_t maxlength, const char *search, const char *replace, bool caseSensitive);
size_t UTIL_ReplaceAll(char *subject, size_t maxlength, const char *search, size_t searchLen, const char *replace, size_t replaceLen, bool caseSensitive);
char *UTIL_ReplaceEx(char *subject, size_t maxLen, const char *search, size_t searchLen, const char *replace, size_t replaceLen, bool caseSensitive);
void UTIL_TrimLeft(char *buffer);
void UTIL_TrimRight(char *buffer);
char* utf8stristr(const char *string1, const char *string2);
int utf8strncasecmp(const char *string1, const char *string2, size_t n);
int utf8strcasecmp(const char *string1, const char *string2);
#define GET_PLAYER_POINTER(e) (&g_players[ENTINDEX(e)])
//#define GET_PLAYER_POINTER(e) (&g_players[(((int)e-g_edict_point)/sizeof(edict_t))])
#define GET_PLAYER_POINTER_I(i) (&g_players[i])
@ -251,10 +258,6 @@ int loadModules(const char* filename, PLUG_LOADTIME now);
void detachModules();
void detachReloadModules();
#ifdef FAKEMETA
void attachModules();
#endif
// Count modules
enum CountModulesMode
{
@ -281,6 +284,7 @@ extern "C" size_t get_amxstring_r(AMX *amx, cell amx_addr, char *destination, in
int amxstring_len(cell* cstr);
int load_amxscript(AMX* amx, void** program, const char* path, char error[64], int debug);
int load_amxscript_ex(AMX* amx, void** program, const char* path, char *error, size_t maxLength, int debug);
int set_amxnatives(AMX* amx, char error[64]);
int set_amxstring(AMX *amx, cell amx_addr, const char *source, int max);
int set_amxstring_simple(cell *dest, const char *source, int max);
@ -293,11 +297,8 @@ void copy_amxmemory(cell* dest, cell* src, int len);
void get_modname(char*);
void print_srvconsole(const char *fmt, ...);
void report_error(int code, const char* fmt, ...);
void* alloc_amxmemory(void**, int size);
void free_amxmemory(void **ptr);
// get_localinfo
const char* get_localinfo(const char* name, const char* def);
cell AMX_NATIVE_CALL require_module(AMX *amx, cell *params);
extern "C" void LogError(AMX *amx, int err, const char *fmt, ...);
enum ModuleCallReason

View File

@ -1,11 +0,0 @@
; /usr/local/cross-tools/bin/i386-mingw32msvc-dlltool --base-file /tmp/cc4kB6s0.base --output-exp amx_mm.exp --dllname amx_mm.dll --output-def amx_mm.def --add-stdcall-alias --exclude-symbol=DllMainCRTStartup@12 --def /tmp/ccyI7I7K.def
EXPORTS
GetEngineFunctions @ 1 ;
GetEngineFunctions_Post @ 2 ;
GetEntityAPI2 @ 3 ;
GetEntityAPI2_Post @ 4 ;
GiveFnptrsToDll = GiveFnptrsToDll@8 @ 5 ;
GiveFnptrsToDll@8 @ 6 ;
Meta_Attach @ 7 ;
Meta_Detach @ 8 ;
Meta_Query @ 9 ;

View File

@ -87,6 +87,7 @@ void Client_TeamInfo(void* mValue)
case 1:
if (index < 1 || index > gpGlobals->maxClients) break;
char* msg = (char*)mValue;
if (!msg) break;
g_players[index].team = msg;
g_teamsIds.registerTeam(msg, -1);
g_players[index].teamId = g_teamsIds.findTeamId(msg);

View File

@ -744,9 +744,15 @@ enum FileType
struct DirectoryHandle
{
DirectoryHandle(void* handle_, bool valvefs_) : handle(handle_), valvefs(valvefs_) {}
DirectoryHandle(CDirectory *handle_) : handle(handle_), valvefs(false) {}
DirectoryHandle(FileFindHandle_t handle_) : handle_vfs(handle_), valvefs(true) {}
union
{
CDirectory* handle;
FileFindHandle_t handle_vfs;
};
void* handle;
bool valvefs;
};
@ -768,7 +774,7 @@ static cell AMX_NATIVE_CALL amx_open_dir(AMX *amx, cell *params)
const char* wildcardedPath = g_LibSys.PathFormat("%s%s*", path, (path[length - 1] != '/' && path[length - 1] != '\\') ? "/" : "");
const char* pathID = get_amxstring_null(amx, params[6], 1, length);
static FileFindHandle_t handle;
FileFindHandle_t handle;
const char* pFirst = g_FileSystem->FindFirst(wildcardedPath, &handle, pathID);
if (!pFirst)
@ -781,7 +787,7 @@ static cell AMX_NATIVE_CALL amx_open_dir(AMX *amx, cell *params)
*fileType = g_FileSystem->FindIsDirectory(handle) ? FileType_Directory : FileType_File;
return reinterpret_cast<cell>(new DirectoryHandle(reinterpret_cast<void*>(&handle), true));
return reinterpret_cast<cell>(new DirectoryHandle(handle));
}
CDirectory* dir = g_LibSys.OpenDirectory(build_pathname("%s", path));
@ -800,7 +806,7 @@ static cell AMX_NATIVE_CALL amx_open_dir(AMX *amx, cell *params)
const char* entry = dir->GetEntryName();
set_amxstring_utf8(amx, params[2], entry, strlen(entry), params[3]);
return reinterpret_cast<cell>(new DirectoryHandle(reinterpret_cast<void*>(dir), false));
return reinterpret_cast<cell>(new DirectoryHandle(dir));
}
// native close_dir(dirh);
@ -815,8 +821,8 @@ static cell AMX_NATIVE_CALL amx_close_dir(AMX *amx, cell *params)
if (p->valvefs)
{
FileFindHandle_t* handle = reinterpret_cast<FileFindHandle_t*>(p->handle);
g_FileSystem->FindClose(*handle);
FileFindHandle_t handle = p->handle_vfs;
g_FileSystem->FindClose(handle);
}
else
{
@ -841,14 +847,9 @@ static cell AMX_NATIVE_CALL amx_get_dir(AMX *amx, cell *params)
if (p->valvefs)
{
FileFindHandle_t* handle = reinterpret_cast<FileFindHandle_t*>(p->handle);
FileFindHandle_t handle = p->handle_vfs;
if (!handle)
{
return 0;
}
const char* entry = g_FileSystem->FindNext(*handle);
const char* entry = g_FileSystem->FindNext(handle);
if (!entry)
{
@ -858,14 +859,14 @@ static cell AMX_NATIVE_CALL amx_get_dir(AMX *amx, cell *params)
if (numParams >= 4)
{
cell* fileType = get_amxaddr(amx, params[4]);
*fileType = g_FileSystem->FindIsDirectory(*handle) ? FileType_Directory : FileType_File;
*fileType = g_FileSystem->FindIsDirectory(handle) ? FileType_Directory : FileType_File;
}
set_amxstring_utf8(amx, params[2], entry, strlen(entry), params[3]);
}
else
{
CDirectory* handle = reinterpret_cast<CDirectory*>(p->handle);
CDirectory* handle = p->handle;
if (!handle)
{

View File

@ -120,6 +120,9 @@ int mState;
int g_srvindex;
CDetour *DropClientDetour;
bool g_isDropClientHookEnabled = false;
bool g_isDropClientHookAvailable = false;
void SV_DropClient_RH(IRehldsHook_SV_DropClient *chain, IGameClient *cl, bool crash, const char *format);
cvar_t init_amxmodx_version = {"amxmodx_version", "", FCVAR_SERVER | FCVAR_SPONLY};
cvar_t init_amxmodx_modules = {"amxmodx_modules", "", FCVAR_SPONLY};
@ -414,6 +417,7 @@ int C_Spawn(edict_t *pent)
ArrayHandles.clear();
TrieHandles.clear();
TrieIterHandles.clear();
TrieSnapshotHandles.clear();
DataPackHandles.clear();
TextParsersHandles.clear();
@ -623,10 +627,21 @@ void C_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
}
}
if (DropClientDetour)
if (g_isDropClientHookAvailable)
{
if (!g_isDropClientHookEnabled)
{
if (RehldsApi)
{
RehldsHookchains->SV_DropClient()->registerHook(SV_DropClient_RH);
}
else
{
DropClientDetour->EnableDetour();
}
g_isDropClientHookEnabled = true;
}
}
RETURN_META(MRES_IGNORED);
}
@ -642,10 +657,11 @@ void C_ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax)
pPlayer->Init(pEdictList + i, i);
}
CoreCfg.ExecuteMainConfig(); // Execute amxx.cfg
executeForwards(FF_PluginInit);
executeForwards(FF_PluginCfg);
CoreCfg.ExecuteMainConfig(); // Execute amxx.cfg
CoreCfg.ExecuteAutoConfigs(); // Execute configs created with AutoExecConfig native.
CoreCfg.SetMapConfigTimer(6.1); // Prepare per-map configs to be executed 6.1 seconds later.
// Original value which was used in admin.sma.
@ -683,7 +699,7 @@ void C_ServerDeactivate()
// deprecated
executeForwards(FF_ClientDisconnect, static_cast<cell>(pPlayer->index));
if (DropClientDetour && !pPlayer->disconnecting)
if (g_isDropClientHookAvailable && !pPlayer->disconnecting)
{
executeForwards(FF_ClientDisconnected, static_cast<cell>(pPlayer->index), FALSE, prepareCharArray(const_cast<char*>(""), 0), 0);
}
@ -696,17 +712,28 @@ void C_ServerDeactivate()
pPlayer->Disconnect();
--g_players_num;
if (!wasDisconnecting && DropClientDetour)
if (!wasDisconnecting && g_isDropClientHookAvailable)
{
executeForwards(FF_ClientRemove, static_cast<cell>(pPlayer->index), FALSE, const_cast<char*>(""));
}
}
}
if (DropClientDetour)
if (g_isDropClientHookAvailable)
{
if (g_isDropClientHookEnabled)
{
if (RehldsApi)
{
RehldsHookchains->SV_DropClient()->unregisterHook(SV_DropClient_RH);
}
else
{
DropClientDetour->DisableDetour();
}
g_isDropClientHookEnabled = false;
}
}
g_players_num = 0;
executeForwards(FF_PluginEnd);
@ -725,8 +752,6 @@ void C_ServerDeactivate_Post()
modules_callPluginsUnloading();
detachReloadModules();
CoreCfg.Clear();
g_auth.clear();
@ -750,6 +775,8 @@ void C_ServerDeactivate_Post()
ClearPluginLibraries();
modules_callPluginsUnloaded();
detachReloadModules();
ClearMessages();
// Flush the dynamic admins list
@ -880,7 +907,7 @@ void C_ClientDisconnect(edict_t *pEntity)
// deprecated
executeForwards(FF_ClientDisconnect, static_cast<cell>(pPlayer->index));
if (DropClientDetour && !pPlayer->disconnecting)
if (g_isDropClientHookAvailable && !pPlayer->disconnecting)
{
executeForwards(FF_ClientDisconnected, static_cast<cell>(pPlayer->index), FALSE, prepareCharArray(const_cast<char*>(""), 0), 0);
}
@ -895,7 +922,7 @@ void C_ClientDisconnect(edict_t *pEntity)
pPlayer->Disconnect();
if (!wasDisconnecting && DropClientDetour)
if (!wasDisconnecting && g_isDropClientHookAvailable)
{
executeForwards(FF_ClientRemove, static_cast<cell>(pPlayer->index), FALSE, const_cast<char*>(""));
}
@ -1414,8 +1441,15 @@ int C_Cmd_Argc(void)
// Only here we may find out who is an owner.
void C_SetModel(edict_t *e, const char *m)
{
if (e->v.owner && m[7]=='w' && m[8]=='_' && m[9]=='h')
g_grenades.put(e, 1.75, 4, GET_PLAYER_POINTER(e->v.owner));
if (!m || strcmp(m, "models/w_hegrenade.mdl") != 0)
{
RETURN_META(MRES_IGNORED);
}
if (e->v.owner)
{
g_grenades.put(e, 1.75f, 4, GET_PLAYER_POINTER(e->v.owner));
}
RETURN_META(MRES_IGNORED);
}
@ -1644,6 +1678,8 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
if (RehldsApi_Init())
{
RehldsHookchains->SV_DropClient()->registerHook(SV_DropClient_RH);
g_isDropClientHookAvailable = true;
g_isDropClientHookEnabled = true;
}
else
{
@ -1652,6 +1688,8 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
if (CommonConfig && CommonConfig->GetMemSig("SV_DropClient", &address) && address)
{
DropClientDetour = DETOUR_CREATE_STATIC_FIXED(SV_DropClient, address);
g_isDropClientHookAvailable = true;
g_isDropClientHookEnabled = true;
}
else
{
@ -1707,93 +1745,30 @@ C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
ClearLibraries(LibSource_Plugin);
ClearLibraries(LibSource_Module);
if (DropClientDetour)
if (g_isDropClientHookAvailable)
{
if (RehldsApi)
{
if (g_isDropClientHookEnabled)
{
RehldsHookchains->SV_DropClient()->unregisterHook(SV_DropClient_RH);
}
}
else
{
DropClientDetour->Destroy();
}
else if (RehldsApi)
{
RehldsHookchains->SV_DropClient()->unregisterHook(SV_DropClient_RH);
g_isDropClientHookAvailable = false;
g_isDropClientHookEnabled = false;
}
return (TRUE);
}
#if defined(__linux__) || defined(__APPLE__)
// linux prototype
C_DLLEXPORT void GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals)
C_DLLEXPORT void WINAPI GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals)
{
#else
#ifdef _MSC_VER
// MSVC: Simulate __stdcall calling convention
C_DLLEXPORT __declspec(naked) void GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals)
{
__asm // Prolog
{
// Save ebp
push ebp
// Set stack frame pointer
mov ebp, esp
// Allocate space for local variables
// The MSVC compiler gives us the needed size in __LOCAL_SIZE.
sub esp, __LOCAL_SIZE
// Push registers
push ebx
push esi
push edi
}
#else // _MSC_VER
#ifdef __GNUC__
// GCC can also work with this
C_DLLEXPORT void __stdcall GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals)
{
#else // __GNUC__
// compiler not known
#error There is no support (yet) for your compiler. Please use MSVC or GCC compilers or contact the AMX Mod X dev team.
#endif // __GNUC__
#endif // _MSC_VER
#endif // __linux__
// ** Function core <--
memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t));
gpGlobals = pGlobals;
// --> ** Function core
#ifdef _MSC_VER
// Epilog
if (sizeof(int*) == 8)
{ // 64 bit
__asm
{
// Pop registers
pop edi
pop esi
pop ebx
// Restore stack frame pointer
mov esp, ebp
// Restore ebp
pop ebp
// 2 * sizeof(int*) = 16 on 64 bit
ret 16
}
}
else
{ // 32 bit
__asm
{
// Pop registers
pop edi
pop esi
pop ebx
// Restore stack frame pointer
mov esp, ebp
// Restore ebp
pop ebp
// 2 * sizeof(int*) = 8 on 32 bit
ret 8
}
}
#endif // #ifdef _MSC_VER
}
DLL_FUNCTIONS gFunctionTable;

View File

@ -76,18 +76,6 @@ void print_srvconsole(const char *fmt, ...)
SERVER_PRINT(string);
}
void* alloc_amxmemory(void** p, int size)
{
*p = new unsigned char[size];
return *p;
}
void free_amxmemory(void **ptr)
{
delete[] (unsigned char *)(*ptr);
*ptr = 0;
}
#if defined BINLOG_ENABLED
void BinLog_LogNative(AMX *amx, int native, int params)
{
@ -120,7 +108,7 @@ static binlogfuncs_t logfuncs =
};
#endif
int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug)
int load_amxscript_internal(AMX *amx, void **program, const char *filename, char *error, size_t maxLength, int debug)
{
*error = 0;
size_t bufSize;
@ -139,7 +127,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
if (!*program)
{
strcpy(error, "Failed to allocate memory");
ke::SafeStrcpy(error, maxLength, "Failed to allocate memory");
return (amx->error = AMX_ERR_MEMORY);
}
@ -152,31 +140,31 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
case CAmxxReader::Err_None:
break;
case CAmxxReader::Err_FileOpen:
strcpy(error, "Plugin file open error");
ke::SafeStrcpy(error, maxLength, "Plugin file open error");
return (amx->error = AMX_ERR_NOTFOUND);
case CAmxxReader::Err_FileRead:
strcpy(error, "Plugin file read error");
ke::SafeStrcpy(error, maxLength, "Plugin file read error");
return (amx->error = AMX_ERR_NOTFOUND);
case CAmxxReader::Err_InvalidParam:
strcpy(error, "Internal error: Invalid parameter");
ke::SafeStrcpy(error, maxLength, "Internal error: Invalid parameter");
return (amx->error = AMX_ERR_NOTFOUND);
case CAmxxReader::Err_FileInvalid:
strcpy(error, "Invalid Plugin");
ke::SafeStrcpy(error, maxLength, "Invalid Plugin");
return (amx->error = AMX_ERR_FORMAT);
case CAmxxReader::Err_SectionNotFound:
strcpy(error, "Searched section not found (.amxx)");
ke::SafeStrcpy(error, maxLength, "Searched section not found (.amxx)");
return (amx->error = AMX_ERR_NOTFOUND);
case CAmxxReader::Err_DecompressorInit:
strcpy(error, "Decompressor initialization failed");
ke::SafeStrcpy(error, maxLength, "Decompressor initialization failed");
return (amx->error = AMX_ERR_INIT);
case CAmxxReader::Err_Decompress:
strcpy(error, "Internal error: Decompress");
ke::SafeStrcpy(error, maxLength, "Internal error: Decompress");
return (amx->error = AMX_ERR_NOTFOUND);
case CAmxxReader::Err_OldFile:
strcpy(error, "Plugin uses deprecated format. Update compiler");
ke::SafeStrcpy(error, maxLength, "Plugin uses deprecated format. Update compiler");
return (amx->error = AMX_ERR_FORMAT);
default:
strcpy(error, "Unknown error");
ke::SafeStrcpy(error, maxLength, "Unknown error");
return (amx->error = AMX_ERR_NOTFOUND);
}
} else {
@ -190,7 +178,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
if (magic != AMX_MAGIC)
{
strcpy(error, "Invalid Plugin");
ke::SafeStrcpy(error, maxLength, "Invalid Plugin");
return (amx->error = AMX_ERR_FORMAT);
}
@ -203,7 +191,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
{
if ((hdr->file_version < CUR_FILE_VERSION))
{
sprintf(error, "Plugin needs newer debug version info");
ke::SafeStrcpy(error, maxLength, "Plugin needs newer debug version info");
return (amx->error = AMX_ERR_VERSION);
}
else if ((hdr->flags & AMX_FLAG_DEBUG) != 0)
@ -221,13 +209,13 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
{
dbg_FreeInfo(pDbg);
delete pDbg;
sprintf(error, "Debug loading error %d", err);
ke::SafeSprintf(error, maxLength, "Debug loading error %d", err);
return (amx->error = AMX_ERR_INIT);
}
amx->flags |= AMX_FLAG_DEBUG;
} else {
sprintf(error, "Plugin not compiled with debug option");
ke::SafeStrcpy(error, maxLength, "Plugin not compiled with debug option");
return (amx->error = AMX_ERR_INIT);
}
} else {
@ -250,7 +238,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
delete pDbg;
}
sprintf(error, "Load error %d (invalid file format or version)", err);
ke::SafeSprintf(error, maxLength, "Load error %d (invalid file format or version)", err);
return (amx->error = AMX_ERR_INIT);
}
@ -288,7 +276,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
{
delete[] np;
delete[] rt;
strcpy(error, "Failed to initialize JIT'd plugin");
ke::SafeStrcpy(error, maxLength, "Failed to initialize JIT'd plugin");
return (amx->error = AMX_ERR_INIT);
}
@ -319,14 +307,14 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
if (*program == 0)
{
strcpy(error, "Failed to allocate memory");
ke::SafeStrcpy(error, maxLength, "Failed to allocate memory");
return (amx->error = AMX_ERR_MEMORY);
}
} else {
delete[] np;
delete[] rt;
sprintf(error, "Failed to initialize plugin (%d)", err);
ke::SafeSprintf(error, maxLength, "Failed to initialize plugin (%d)", err);
return (amx->error = AMX_ERR_INIT_JIT);
}
@ -337,7 +325,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
if (!script)
{
ke::SafeSprintf(error, 64, "Failed to allocate memory for script");
ke::SafeStrcpy(error, maxLength, "Failed to allocate memory for script");
return (amx->error = AMX_ERR_MEMORY);
}
@ -353,7 +341,7 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
{
if (amx_Register(amx, core_Natives, -1) != AMX_ERR_NONE)
{
sprintf(error, "Plugin uses an unknown function (name \"%s\") - check your modules.ini.", no_function);
ke::SafeSprintf(error, maxLength, "Plugin uses an unknown function (name \"%s\") - check your modules.ini.", no_function);
return (amx->error = AMX_ERR_NOTFOUND);
}
} else {
@ -364,6 +352,17 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
return (amx->error = AMX_ERR_NONE);
}
int load_amxscript_ex(AMX *amx, void **program, const char *filename, char *error, size_t maxLength, int debug)
{
return load_amxscript_internal(amx, program, filename, error, maxLength, debug);
}
// Deprecated. Use load_amxscript_ex() or MF_LoadAmxScriptEx() for modules. This function is kept to maintain backward compatibility.
int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug)
{
return load_amxscript_internal(amx, program, filename, error, 64 /* error max length */, debug);
}
const char *StrCaseStr(const char *as, const char *bs)
{
static char a[256];
@ -876,10 +875,10 @@ bool LoadModule(const char *shortname, PLUG_LOADTIME now, bool simplify, bool no
report_error(1, "[AMXX] Couldn't find info about module (file \"%s\")", path);
break;
case MODULE_NOQUERY:
report_error(1, "[AMXX] Couldn't find \"AMX_Query\" or \"AMXX_Query\" (file \"%s\")", path);
report_error(1, "[AMXX] Couldn't find \"AMXX_Query\" (file \"%s\")", path);
break;
case MODULE_NOATTACH:
report_error(1, "[AMXX] Couldn't find \"%s\" (file \"%s\")", module->isAmxx() ? "AMXX_Attach" : "AMX_Attach", path);
report_error(1, "[AMXX] Couldn't find \"AMXX_Attach\" (file \"%s\")", path);
break;
case MODULE_OLD:
report_error(1, "[AMXX] Module has a different interface version (file \"%s\")", path);
@ -920,7 +919,7 @@ bool LoadModule(const char *shortname, PLUG_LOADTIME now, bool simplify, bool no
bool retVal = module->attachModule();
if (module->isAmxx() && !retVal)
if (!retVal)
{
switch (module->getStatusValue())
{
@ -1026,23 +1025,6 @@ void detachReloadModules()
}
}
const char* strip_name(const char* a)
{
const char* ret = a;
while (*a)
{
if (*a == '/' || *a == '\\')
{
ret = ++a;
continue;
}
++a;
}
return ret;
}
// Get the number of running modules
int countModules(CountModulesMode mode)
{
@ -1788,7 +1770,8 @@ void Module_CacheFunctions()
REGISTER_FUNC("GetAmxScriptName", MNF_GetAmxScriptName)
REGISTER_FUNC("FindAmxScriptByName", MNF_FindAmxScriptByName)
REGISTER_FUNC("FindAmxScriptByAmx", MNF_FindAmxScriptByAmx)
REGISTER_FUNC("LoadAmxScript", load_amxscript)
REGISTER_FUNC("LoadAmxScript", load_amxscript) // Deprecated. Please use LoadAmxScriptEx instead.
REGISTER_FUNC("LoadAmxScriptEx", load_amxscript_ex)
REGISTER_FUNC("UnloadAmxScript", unload_amxscript)
// String / mem in amx scripts support

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
# Visual Studio 15
VisualStudioVersion = 15.0.26730.16
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx_mm", "amxmodx_mm.vcxproj", "{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
EndProject
@ -51,6 +51,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxxpc", "..\..\compiler\am
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpc300", "..\..\compiler\libpc300\libpc300.vcxproj", "{19B72687-080B-437A-917A-12AEB0031635}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "json", "..\..\modules\json\msvc12\json.vcxproj", "{4CF9D220-F318-4D1C-81DF-E2377A2D8FFE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -326,6 +328,18 @@ Global
{19B72687-080B-437A-917A-12AEB0031635}.JITReleaseBinLog|Win32.Build.0 = Release|Win32
{19B72687-080B-437A-917A-12AEB0031635}.Release|Win32.ActiveCfg = Release|Win32
{19B72687-080B-437A-917A-12AEB0031635}.Release|Win32.Build.0 = Release|Win32
{4CF9D220-F318-4D1C-81DF-E2377A2D8FFE}.Debug|Win32.ActiveCfg = Debug|Win32
{4CF9D220-F318-4D1C-81DF-E2377A2D8FFE}.Debug|Win32.Build.0 = Debug|Win32
{4CF9D220-F318-4D1C-81DF-E2377A2D8FFE}.JITDebug|Win32.ActiveCfg = Debug|Win32
{4CF9D220-F318-4D1C-81DF-E2377A2D8FFE}.JITDebug|Win32.Build.0 = Debug|Win32
{4CF9D220-F318-4D1C-81DF-E2377A2D8FFE}.JITDebugBinLog|Win32.ActiveCfg = Debug|Win32
{4CF9D220-F318-4D1C-81DF-E2377A2D8FFE}.JITDebugBinLog|Win32.Build.0 = Debug|Win32
{4CF9D220-F318-4D1C-81DF-E2377A2D8FFE}.JITRelease|Win32.ActiveCfg = Release|Win32
{4CF9D220-F318-4D1C-81DF-E2377A2D8FFE}.JITRelease|Win32.Build.0 = Release|Win32
{4CF9D220-F318-4D1C-81DF-E2377A2D8FFE}.JITReleaseBinLog|Win32.ActiveCfg = Release|Win32
{4CF9D220-F318-4D1C-81DF-E2377A2D8FFE}.JITReleaseBinLog|Win32.Build.0 = Release|Win32
{4CF9D220-F318-4D1C-81DF-E2377A2D8FFE}.Release|Win32.ActiveCfg = Release|Win32
{4CF9D220-F318-4D1C-81DF-E2377A2D8FFE}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -352,5 +366,9 @@ Global
{7F18E00C-6271-4CAB-B18A-746BE3EC68E7} = {1A75873D-E05D-4F07-A4E2-28DC1BB03226}
{39412290-D01C-472F-A439-AB5592A04C08} = {0BB61E37-4EA5-4B18-A164-6CB4810E50F4}
{19B72687-080B-437A-917A-12AEB0031635} = {0BB61E37-4EA5-4B18-A164-6CB4810E50F4}
{4CF9D220-F318-4D1C-81DF-E2377A2D8FFE} = {1A75873D-E05D-4F07-A4E2-28DC1BB03226}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E7D29DAA-4E6E-43AA-A2FC-7BD7758ABFD9}
EndGlobalSection
EndGlobal

View File

@ -60,8 +60,8 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\;..\..\public;..\..\public\memtools;..\..\third_party;..\..\third_party\zlib;..\..\third_party\hashing;..\..\public\sdk;..\..\public\amtl;..\..\third_party;..\..\third_party\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;_CRT_SECURE_NO_DEPRECATE;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\;..\..\public;..\..\public\memtools;..\..\third_party;..\..\third_party\zlib;..\..\third_party\hashing;..\..\third_party\utf8rewind;..\..\public\sdk;..\..\public\amtl;..\..\third_party;..\..\third_party\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;UTF8PROC_EXPORTS;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;_CRT_SECURE_NO_DEPRECATE;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<StructMemberAlignment>4Bytes</StructMemberAlignment>
@ -81,7 +81,7 @@
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/MACHINE:I386 /EXPORT:GiveFnptrsToDll=_GiveFnptrsToDll@8,@1 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>..\JIT\amxjitsn.obj;..\JIT\amxexecn.obj;..\JIT\natives-x86.obj;%(AdditionalDependencies)</AdditionalDependencies>
<Version>0.1</Version>
<SuppressStartupBanner>true</SuppressStartupBanner>
@ -94,7 +94,16 @@
<ImportLibrary>.\jitdebug/amxmodx_mm.lib</ImportLibrary>
<SubSystem>Windows</SubSystem>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<SpecifySectionAttributes>.data,RW</SpecifySectionAttributes>
</Link>
<PreBuildEvent>
<Command>cd ..
md -p JIT 2&gt;NUL
%NASM_PATH%nasm.exe -f win32 helpers-x86.asm -o JIT/helpers-x86.obj
%NASM_PATH%nasm.exe -f win32 natives-x86.asm -o JIT/natives-x86.obj
%NASM_PATH%nasm.exe -f win32 amxexecn.asm -o JIT/amxexecn.obj
%NASM_PATH%nasm.exe -O0 -f win32 amxjitsn.asm -o JIT/amxjitsn.obj</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">
<Midl>
@ -110,8 +119,8 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\;..\..\public;..\..\public\memtools;..\..\third_party;..\..\third_party\zlib;..\..\third_party\hashing;..\..\third_party;..\..\third_party\hashing;..\..\public\sdk;..\..\public\amtl;..\..\third_party;..\..\third_party\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\;..\..\public;..\..\public\memtools;..\..\third_party;..\..\third_party\zlib;..\..\third_party\hashing;..\..\third_party\utf8rewind;..\..\third_party;..\..\third_party\hashing;..\..\public\sdk;..\..\public\amtl;..\..\third_party;..\..\third_party\hashing;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;UTF8PROC_EXPORTS;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@ -132,7 +141,7 @@
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/MACHINE:I386 /EXPORT:GiveFnptrsToDll=_GiveFnptrsToDll@8,@1 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>..\JIT\amxjitsn.obj;..\JIT\amxexecn.obj;..\JIT\natives-x86.obj;%(AdditionalDependencies)</AdditionalDependencies>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\extra\lib_win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@ -145,7 +154,16 @@
<ImportLibrary>.\jitrelease/amxmodx_mm.lib</ImportLibrary>
<SubSystem>Windows</SubSystem>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<SpecifySectionAttributes>.data,RW</SpecifySectionAttributes>
</Link>
<PreBuildEvent>
<Command>cd ..
md -p JIT 2&gt;NUL
%NASM_PATH%nasm.exe -f win32 helpers-x86.asm -o JIT/helpers-x86.obj
%NASM_PATH%nasm.exe -f win32 natives-x86.asm -o JIT/natives-x86.obj
%NASM_PATH%nasm.exe -f win32 amxexecn.asm -o JIT/amxexecn.obj
%NASM_PATH%nasm.exe -O0 -f win32 amxjitsn.asm -o JIT/amxjitsn.obj</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\public\memtools\CDetour\asm\asm.c" />
@ -180,6 +198,42 @@
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">$(IntDir)hashing\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">$(IntDir)hashing\</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\internal\casemapping.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\internal\codepoint.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\internal\composition.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\internal\database.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\internal\decomposition.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\internal\seeking.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\internal\streaming.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\unicodedatabase.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\utf8rewind.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\..\third_party\zlib\adler32.c">
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">$(IntDir)zlib\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">$(IntDir)zlib\</ObjectFileName>
@ -326,6 +380,16 @@
<ClInclude Include="..\..\third_party\hashing\hashers\sha256.h" />
<ClInclude Include="..\..\third_party\hashing\hashers\sha3.h" />
<ClInclude Include="..\..\third_party\hashing\hashing.h" />
<ClInclude Include="..\..\third_party\utf8rewind\internal\base.h" />
<ClInclude Include="..\..\third_party\utf8rewind\internal\casemapping.h" />
<ClInclude Include="..\..\third_party\utf8rewind\internal\codepoint.h" />
<ClInclude Include="..\..\third_party\utf8rewind\internal\composition.h" />
<ClInclude Include="..\..\third_party\utf8rewind\internal\database.h" />
<ClInclude Include="..\..\third_party\utf8rewind\internal\decomposition.h" />
<ClInclude Include="..\..\third_party\utf8rewind\internal\seeking.h" />
<ClInclude Include="..\..\third_party\utf8rewind\internal\streaming.h" />
<ClInclude Include="..\..\third_party\utf8rewind\unicodedatabase.h" />
<ClInclude Include="..\..\third_party\utf8rewind\utf8rewind.h" />
<ClInclude Include="..\..\third_party\zlib\crc32.h" />
<ClInclude Include="..\..\third_party\zlib\deflate.h" />
<ClInclude Include="..\..\third_party\zlib\gzguts.h" />
@ -382,7 +446,10 @@
<ClInclude Include="..\..\public\sdk\moduleconfig.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\version.rc" />
<ResourceCompile Include="..\version.rc">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">../../public;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">../../public;</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\plugins\include\cellstack.inc" />
@ -390,6 +457,9 @@
<None Include="..\..\plugins\include\cvars.inc" />
<None Include="..\..\plugins\include\datapack.inc" />
<None Include="..\..\plugins\include\gameconfig.inc" />
<None Include="..\..\plugins\include\newmenus.inc" />
<None Include="..\..\plugins\include\string_const.inc" />
<None Include="..\..\plugins\include\string_stocks.inc" />
<None Include="..\..\plugins\include\textparse_ini.inc" />
<None Include="..\..\plugins\include\textparse_smc.inc" />
<None Include="..\amxdefn.asm" />

View File

@ -55,6 +55,12 @@
<Filter Include="ReSDK\engine">
<UniqueIdentifier>{04fab577-6f56-40d0-8f69-7ce1b8bf3bb9}</UniqueIdentifier>
</Filter>
<Filter Include="Third Party\UTF8Rewind">
<UniqueIdentifier>{270f3524-564f-4154-bb35-242a6faac09e}</UniqueIdentifier>
</Filter>
<Filter Include="Third Party\UTF8Rewind\internal">
<UniqueIdentifier>{295b670a-1aa3-4b80-bbf6-4ba422672274}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\amx.cpp">
@ -303,6 +309,33 @@
<ClCompile Include="..\..\public\resdk\mod_rehlds_api.cpp">
<Filter>ReSDK</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\unicodedatabase.c">
<Filter>Third Party\UTF8Rewind</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\utf8rewind.c">
<Filter>Third Party\UTF8Rewind</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\internal\casemapping.c">
<Filter>Third Party\UTF8Rewind\internal</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\internal\codepoint.c">
<Filter>Third Party\UTF8Rewind\internal</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\internal\composition.c">
<Filter>Third Party\UTF8Rewind\internal</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\internal\database.c">
<Filter>Third Party\UTF8Rewind\internal</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\internal\decomposition.c">
<Filter>Third Party\UTF8Rewind\internal</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\internal\seeking.c">
<Filter>Third Party\UTF8Rewind\internal</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\utf8rewind\internal\streaming.c">
<Filter>Third Party\UTF8Rewind\internal</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\amx.h">
@ -506,8 +539,35 @@
<ClInclude Include="..\CoreConfig.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\CFrameAction.h">
<Filter>Header Files</Filter>
<ClInclude Include="..\..\third_party\utf8rewind\unicodedatabase.h">
<Filter>Third Party\UTF8Rewind</Filter>
</ClInclude>
<ClInclude Include="..\..\third_party\utf8rewind\internal\base.h">
<Filter>Third Party\UTF8Rewind\internal</Filter>
</ClInclude>
<ClInclude Include="..\..\third_party\utf8rewind\internal\casemapping.h">
<Filter>Third Party\UTF8Rewind\internal</Filter>
</ClInclude>
<ClInclude Include="..\..\third_party\utf8rewind\internal\codepoint.h">
<Filter>Third Party\UTF8Rewind\internal</Filter>
</ClInclude>
<ClInclude Include="..\..\third_party\utf8rewind\internal\composition.h">
<Filter>Third Party\UTF8Rewind\internal</Filter>
</ClInclude>
<ClInclude Include="..\..\third_party\utf8rewind\internal\database.h">
<Filter>Third Party\UTF8Rewind\internal</Filter>
</ClInclude>
<ClInclude Include="..\..\third_party\utf8rewind\internal\decomposition.h">
<Filter>Third Party\UTF8Rewind\internal</Filter>
</ClInclude>
<ClInclude Include="..\..\third_party\utf8rewind\internal\seeking.h">
<Filter>Third Party\UTF8Rewind\internal</Filter>
</ClInclude>
<ClInclude Include="..\..\third_party\utf8rewind\internal\streaming.h">
<Filter>Third Party\UTF8Rewind\internal</Filter>
</ClInclude>
<ClInclude Include="..\..\third_party\utf8rewind\utf8rewind.h">
<Filter>Third Party\UTF8Rewind</Filter>
</ClInclude>
<ClInclude Include="..\..\public\resdk\common\hookchains.h">
<Filter>ReSDK\common</Filter>
@ -521,6 +581,9 @@
<ClInclude Include="..\..\public\resdk\mod_rehlds_api.h">
<Filter>ReSDK</Filter>
</ClInclude>
<ClInclude Include="..\CFrameAction.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\version.rc">
@ -624,6 +687,15 @@
<None Include="..\..\plugins\include\cstrike_const.inc">
<Filter>Pawn Includes</Filter>
</None>
<None Include="..\..\plugins\include\string_const.inc">
<Filter>Pawn Includes</Filter>
</None>
<None Include="..\..\plugins\include\string_stocks.inc">
<Filter>Pawn Includes</Filter>
</None>
<None Include="..\..\plugins\include\newmenus.inc">
<Filter>Pawn Includes</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Object Include="..\Jit\helpers-x86.obj">

View File

@ -11,6 +11,7 @@
#define _NATIVES_NATIVES_HANDLES_H_
#include <amtl/am-vector.h>
#include <amtl/am-autoptr.h>
// Note: All handles start at 1. 0 and below are invalid handles.
// This way, a plugin that doesn't initialize a vector or
@ -22,7 +23,7 @@ class NativeHandle
{
private:
ke::Vector<T*> m_handles;
ke::Vector<ke::AutoPtr<T>> m_handles;
public:
@ -34,69 +35,66 @@ class NativeHandle
void clear()
{
for (size_t i = 0; i < m_handles.length(); ++i)
{
if (m_handles[i])
{
delete m_handles[i];
}
}
m_handles.clear();
}
T *lookup(int handle)
size_t size()
{
return m_handles.length();
}
T *lookup(size_t handle)
{
--handle;
if (handle < 0 || handle >= static_cast<int>(m_handles.length()))
if (handle >= m_handles.length())
{
return nullptr;
}
return m_handles[handle];
return m_handles[handle].get();
}
template <typename... Targs>
int create(Targs... Fargs)
size_t create(Targs... Fargs)
{
for (size_t i = 0; i < m_handles.length(); ++i)
{
if (!m_handles[i])
{
m_handles[i] = new T(Fargs...);
m_handles[i] = ke::AutoPtr<T>(new T(Fargs...));
return static_cast<int>(i) + 1;
return i + 1;
}
}
m_handles.append(new T(Fargs...));
m_handles.append(ke::AutoPtr<T>(new T(Fargs...)));
return m_handles.length();
}
int clone(T *data)
size_t clone(T *data)
{
for (size_t i = 0; i < m_handles.length(); ++i)
{
if (!m_handles[i])
{
m_handles[i] = data;
m_handles[i] = ke::AutoPtr<T>(data);
return static_cast<int>(i) + 1;
return i + 1;
}
}
m_handles.append(data);
m_handles.append(ke::AutoPtr<T>(data));
return m_handles.length();
}
bool destroy(int handle)
bool destroy(size_t handle)
{
handle--;
--handle;
if (handle < 0 || handle >= static_cast<int>(m_handles.length()))
if (handle >= m_handles.length())
{
return false;
}
@ -106,7 +104,6 @@ class NativeHandle
return false;
}
delete m_handles[handle];
m_handles[handle] = nullptr;
return true;

View File

@ -10,6 +10,7 @@
#include "amxmodx.h"
#include "CMenu.h"
#include "newmenus.h"
#include "format.h"
#include "CDataPack.h"
ke::Vector<Menu *> g_NewMenus;
@ -91,9 +92,9 @@ bool CloseNewMenus(CPlayer *pPlayer)
return true;
}
Menu::Menu(const char *title, AMX *amx, int fid) : m_Title(title), m_ItemColor("\\r"),
Menu::Menu(const char *title, AMX *amx, int fid, bool use_ml) : m_Title(title), m_ItemColor("\\r"),
m_NeverExit(false), m_AutoColors(g_coloredmenus), thisId(0), func(fid),
isDestroying(false), pageCallback(-1), items_per_page(7)
isDestroying(false), pageCallback(-1), showPageNumber(true), useMultilingual(use_ml), amx(amx), items_per_page(7)
{
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
menuId = g_menucmds.registerMenuId(title, amx);
@ -320,11 +321,6 @@ bool Menu::Display(int player, page_t page)
CPlayer *pPlayer = GET_PLAYER_POINTER_I(player);
pPlayer->keys = 0;
pPlayer->menu = 0;
UTIL_FakeClientCommand(pPlayer->pEdict, "menuselect", "10", 0);
pPlayer->keys = keys;
pPlayer->menu = menuId;
pPlayer->newmenu = thisId;
@ -365,18 +361,32 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
m_Text = nullptr;
auto title = m_Title.chars();
if (this->useMultilingual)
{
const auto language = playerlang(player);
const auto definition = translate(this->amx, language, title);
if (definition)
{
title = definition;
}
}
char buffer[255];
if (items_per_page && (pages != 1))
if (showPageNumber && items_per_page && (pages != 1))
{
if (m_AutoColors)
ke::SafeSprintf(buffer, sizeof(buffer), "\\y%s %d/%d\n\\w\n", m_Title.chars(), page + 1, pages);
ke::SafeSprintf(buffer, sizeof(buffer), "\\y%s %d/%d\n\\w\n", title, page + 1, pages);
else
ke::SafeSprintf(buffer, sizeof(buffer), "%s %d/%d\n\n", m_Title.chars(), page + 1, pages);
ke::SafeSprintf(buffer, sizeof(buffer), "%s %d/%d\n\n", title, page + 1, pages);
} else {
if (m_AutoColors)
ke::SafeSprintf(buffer, sizeof(buffer), "\\y%s\n\\w\n", m_Title.chars());
ke::SafeSprintf(buffer, sizeof(buffer), "\\y%s\n\\w\n", title);
else
ke::SafeSprintf(buffer, sizeof(buffer), "%s\n\n", m_Title.chars());
ke::SafeSprintf(buffer, sizeof(buffer), "%s\n\n", title);
}
m_Text = m_Text + buffer;
@ -475,24 +485,37 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
option_display = 0;
}
auto itemName = pItem->name.chars();
if (this->useMultilingual)
{
const auto language = playerlang(player);
const auto definition = translate(this->amx, language, itemName);
if (definition)
{
itemName = definition;
}
}
if (pItem->isBlank)
{
ke::SafeSprintf(buffer, sizeof(buffer), "%s\n", pItem->name.chars());
ke::SafeSprintf(buffer, sizeof(buffer), "%s\n", itemName);
}
else if (enabled)
{
if (m_AutoColors)
{
ke::SafeSprintf(buffer, sizeof(buffer), "%s%d.\\w %s\n", m_ItemColor.chars(),option_display, pItem->name.chars());
ke::SafeSprintf(buffer, sizeof(buffer), "%s%d.\\w %s\n", m_ItemColor.chars(),option_display, itemName);
} else {
ke::SafeSprintf(buffer, sizeof(buffer), "%d. %s\n", option_display, pItem->name.chars());
ke::SafeSprintf(buffer, sizeof(buffer), "%d. %s\n", option_display, itemName);
}
} else {
if (m_AutoColors)
{
ke::SafeSprintf(buffer, sizeof(buffer), "\\d%d. %s\n\\w", option_display, pItem->name.chars());
ke::SafeSprintf(buffer, sizeof(buffer), "\\d%d. %s\n\\w", option_display, itemName);
} else {
ke::SafeSprintf(buffer, sizeof(buffer), "#. %s\n", pItem->name.chars());
ke::SafeSprintf(buffer, sizeof(buffer), "#. %s\n", itemName);
}
}
slots++;
@ -633,38 +656,45 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.length()); \
return 0; }
//Makes a new menu handle (-1 for failure)
//native csdm_makemenu(title[]);
// native menu_create(const title[], const handler[], bool:ml = false);
static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
{
int len;
auto title = get_amxstring(amx, params[1], 0, len);
validate_menu_text(title);
auto handler = get_amxstring(amx, params[2], 1, len);
enum args { arg_count, arg_title, arg_handler, arg_ml };
auto func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
int length;
const auto title = get_amxstring(amx, params[arg_title], 0, length);
const auto handler = get_amxstring(amx, params[arg_handler], 1, length);
const auto callback = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
if (func == -1)
if (callback == -1)
{
LogError(amx, AMX_ERR_NOTFOUND, "Invalid function \"%s\"", handler);
LogError(amx, AMX_ERR_NOTFOUND, R"(Invalid function "%s")", handler);
return 0;
}
Menu *pMenu = new Menu(title, amx, func);
validate_menu_text(title);
auto pMenu = new Menu(title, amx, callback, params[arg_ml] != 0);
if (g_MenuFreeStack.empty())
{
g_NewMenus.append(pMenu);
pMenu->thisId = (int)g_NewMenus.length() - 1;
} else {
int pos = g_MenuFreeStack.front();
pMenu->thisId = static_cast<int>(g_NewMenus.length()) - 1;
}
else
{
const auto position = g_MenuFreeStack.front();
g_MenuFreeStack.pop();
g_NewMenus[pos] = pMenu;
pMenu->thisId = pos;
g_NewMenus[position] = pMenu;
pMenu->thisId = position;
}
return pMenu->thisId;
}
static cell AMX_NATIVE_CALL menu_addblank(AMX *amx, cell *params)
{
GETMENU(params[1]);
@ -837,7 +867,8 @@ static cell AMX_NATIVE_CALL menu_items(AMX *amx, cell *params)
//page indices start at 0!
static cell AMX_NATIVE_CALL menu_display(AMX *amx, cell *params)
{
GETMENU(params[2]);
auto handle = params[2];
GETMENU(handle);
int player = params[1];
int page = params[3];
@ -849,6 +880,26 @@ static cell AMX_NATIVE_CALL menu_display(AMX *amx, cell *params)
return 0;
}
if (!g_NewMenus[handle])
{
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d (was previously destroyed).", handle);
return 0;
}
if (g_bmod_cstrike)
{
enum JoinState { Joined = 0 };
enum MenuState { Menu_OFF = 0, Menu_ChooseTeam = 1, Menu_ChooseAppearance = 3 };
GET_OFFSET("CBasePlayer", m_iJoiningState);
GET_OFFSET("CBasePlayer", m_iMenu);
if (get_pdata<int>(pPlayer->pEdict, m_iJoiningState) == Joined || (get_pdata<int>(pPlayer->pEdict, m_iMenu) != Menu_ChooseTeam && get_pdata<int>(pPlayer->pEdict, m_iMenu) != Menu_ChooseAppearance))
{
set_pdata<int>(pPlayer->pEdict, m_iMenu, Menu_OFF);
}
}
int time = -1;
if (params[0] / sizeof(cell) >= 4)
time = params[4];
@ -1021,6 +1072,11 @@ static cell AMX_NATIVE_CALL menu_setprop(AMX *amx, cell *params)
unregisterSPForward(pMenu->pageCallback);
pMenu->pageCallback = callback;
break;
}
case MPROP_SHOWPAGE:
{
pMenu->showPageNumber = (get_amxaddr(amx, params[3]) != 0);
break;
}
case MPROP_SET_NUMBER_COLOR:

View File

@ -31,6 +31,7 @@
#define MPROP_PADMENU 9
#define MPROP_SET_NUMBER_COLOR 10
#define MPROP_PAGE_CALLBACK 11
#define MPROP_SHOWPAGE 12
typedef int (*MENUITEM_CALLBACK)(int, int, int, int);
@ -96,7 +97,7 @@ typedef unsigned int page_t;
class Menu
{
public:
Menu(const char *title, AMX *amx, int fid);
Menu(const char *title, AMX *amx, int fid, bool use_ml);
~Menu();
menuitem *GetMenuItem(item_t item);
@ -127,6 +128,9 @@ public:
int func;
bool isDestroying;
int pageCallback;
bool showPageNumber;
bool useMultilingual;
AMX *amx;
public:
unsigned int items_per_page;
};

View File

@ -1,4 +1,4 @@
// vim: set ts=4 sw=4 tw=99 noet:
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
@ -11,6 +11,7 @@
#include "amxmodx.h"
#include "format.h"
#include "binlog.h"
#include <utf8rewind.h>
const char* stristr(const char* str, const char* substr)
{
@ -169,11 +170,17 @@ extern "C" size_t get_amxstring_r(AMX *amx, cell amx_addr, char *destination, in
return dest - start;
}
char *get_amxbuffer(int id)
{
static char buffer[4][MAX_BUFFER_LENGTH];
return buffer[id];
}
char *get_amxstring(AMX *amx, cell amx_addr, int id, int& len)
{
static char buffer[4][16384];
len = get_amxstring_r(amx, amx_addr, buffer[id], sizeof(buffer[id]) - 1);
return buffer[id];
auto buffer = get_amxbuffer(id);
len = get_amxstring_r(amx, amx_addr, buffer, MAX_BUFFER_LENGTH - 1);
return buffer;
}
char *get_amxstring_null(AMX *amx, cell amx_addr, int id, int& len)
@ -203,6 +210,16 @@ void copy_amxmemory(cell* dest, cell* src, int len)
*dest++=*src++;
}
bool utf8isspace(const char* string)
{
return utf8iscategory(string, 1, UTF8_CATEGORY_ISSPACE) != 0;
}
size_t utf8getspaces(const char* string)
{
return utf8iscategory(string, SIZE_MAX, UTF8_CATEGORY_ISSPACE);
}
char* parse_arg(char** line, int& state)
{
static char arg[3072];
@ -211,7 +228,7 @@ char* parse_arg(char** line, int& state)
while (**line)
{
if (isspace(**line))
if (utf8isspace(*line))
{
if (state == 1)
break;
@ -302,58 +319,68 @@ static cell AMX_NATIVE_CALL replace(AMX *amx, cell *params) /* 4 param */
return 0;
}
// native replace_string(text[], maxlength, const search[], const replace[], bool:caseSensitive = true);
static cell AMX_NATIVE_CALL replace_string(AMX *amx, cell *params)
{
int len;
size_t maxlength = (size_t)params[2];
enum args { arg_count, arg_text, arg_maxlength, arg_search, arg_replace, arg_casesensitive };
char *text = get_amxstring(amx, params[1], 0, len);
const char *search = get_amxstring(amx, params[3], 1, len);
const char *replace = get_amxstring(amx, params[4], 2, len);
auto textLength = 0;
auto searchLength = 0;
auto replaceLength = 0;
bool caseSensitive = params[5] ? true : false;
auto text = get_amxstring(amx, params[arg_text] , 0, textLength);
auto search = get_amxstring(amx, params[arg_search] , 1, searchLength);
auto replace = get_amxstring(amx, params[arg_replace], 2, replaceLength);
if (search[0] == '\0')
auto textMaxLength = params[arg_maxlength];
auto caseSensitive = params[arg_casesensitive] != 0;
if (!*search)
{
LogError(amx, AMX_ERR_NATIVE, "Cannot replace searches of empty strings.");
return -1;
}
int count = UTIL_ReplaceAll(text, maxlength + 1, search, replace, caseSensitive); // + EOS
auto count = UTIL_ReplaceAll(text, textMaxLength + 1, search, searchLength, replace, replaceLength, caseSensitive); // + EOS
set_amxstring(amx, params[1], text, maxlength);
set_amxstring(amx, params[arg_text], text, textMaxLength);
return count;
}
// native replace_stringex(text[], maxlength, const search[], const replace[], searchLen = -1, replaceLen = -1, bool:caseSensitive = true);
static cell AMX_NATIVE_CALL replace_stringex(AMX *amx, cell *params)
{
int len;
size_t maxlength = (size_t)params[2];
enum args { arg_count, arg_text, arg_maxlength, arg_search, arg_replace, arg_searchlen, arg_replacelen, arg_casesensitive };
char *text = get_amxstring(amx, params[1], 0, len);
const char *search = get_amxstring(amx, params[3], 1, len);
const char *replace = get_amxstring(amx, params[4], 2, len);
auto textLength = 0;
auto searchLength = 0;
auto replaceLength = 0;
size_t searchLen = (params[5] == -1) ? strlen(search) : (size_t)params[5];
size_t replaceLen = (params[6] == -1) ? strlen(replace) : (size_t)params[6];
auto text = get_amxstring(amx, params[arg_text] , 0, textLength);
auto search = get_amxstring(amx, params[arg_search] , 1, searchLength);
auto replace = get_amxstring(amx, params[arg_replace], 2, replaceLength);
bool caseSensitive = params[7] ? true : false;
auto textMaxLength = params[arg_maxlength];
auto caseSensitive = params[arg_casesensitive] != 0;
if (searchLen == 0)
if (params[arg_searchlen] != -1) { searchLength = params[arg_searchlen]; }
if (params[arg_replacelen] != -1) { replaceLength = params[arg_replacelen]; }
if (searchLength <= 0)
{
LogError(amx, AMX_ERR_NATIVE, "Cannot replace searches of empty strings.");
return -1;
}
char *ptr = UTIL_ReplaceEx(text, maxlength + 1, search, searchLen, replace, replaceLen, caseSensitive); // + EOS
auto ptr = UTIL_ReplaceEx(text, textMaxLength + 1, search, searchLength, replace, replaceLength, caseSensitive); // + EOS
if (!ptr)
{
return -1;
}
set_amxstring(amx, params[1], text, maxlength);
set_amxstring(amx, params[arg_text], text, textMaxLength);
return ptr - text;
}
@ -382,24 +409,33 @@ static cell AMX_NATIVE_CALL contain(AMX *amx, cell *params) /* 2 param */
return -1;
}
static cell AMX_NATIVE_CALL containi(AMX *amx, cell *params) /* 2 param */
// native containi(const source[], const string[]);
static cell AMX_NATIVE_CALL containi(AMX *amx, cell *params)
{
register cell *a = get_amxaddr(amx, params[2]);
register cell *b = get_amxaddr(amx, params[1]);
register cell *c = b;
cell* str = b;
cell* substr = a;
enum args { arg_count, arg_source, arg_search };
while (*c)
auto sourceLength = 0;
auto searchLength = 0;
auto source = get_amxstring(amx, params[arg_source], 0, sourceLength);
auto search = get_amxstring(amx, params[arg_search], 1, searchLength);
if (sourceLength && searchLength)
{
if (tolower(*c) == tolower(*a))
auto sourceFolded = get_amxbuffer(2);
auto searchFolded = get_amxbuffer(3);
sourceLength = utf8casefold(source, sourceLength, sourceFolded, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
searchLength = utf8casefold(search, searchLength, searchFolded, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
sourceFolded[sourceLength] = '\0';
searchFolded[searchLength] = '\0';
auto result = strstr(sourceFolded, searchFolded);
if (result)
{
c++;
if (!*++a)
return b - str;
} else {
c = ++b;
a = substr;
return result - sourceFolded;
}
}
@ -609,30 +645,34 @@ static cell AMX_NATIVE_CALL equal(AMX *amx, cell *params) /* 3 param */
return ret ? 0 : 1;
}
static cell AMX_NATIVE_CALL equali(AMX *amx, cell *params) /* 3 param */
// native equali(const a[], const b[], c = 0);
static cell AMX_NATIVE_CALL equali(AMX *amx, cell *params)
{
cell *a = get_amxaddr(amx, params[1]);
cell *b = get_amxaddr(amx, params[2]);
int f, l, c = params[3];
enum args { arg_count, arg_string1, arg_string2, arg_numbytes };
if (c)
{
do
{
f = tolower(*a++);
l = tolower(*b++);
} while (--c && l && f && f == l);
auto string1Length = 0;
auto string2Length = 0;
return (f - l) ? 0 : 1;
auto string1 = get_amxstring(amx, params[arg_string1], 0, string1Length);
auto string2 = get_amxstring(amx, params[arg_string2], 1, string2Length);
auto string1Folded = get_amxbuffer(2);
auto string2Folded = get_amxbuffer(3);
string1Length = utf8casefold(string1, string1Length, string1Folded, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
string2Length = utf8casefold(string2, string2Length, string2Folded, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
string1Folded[string1Length] = '\0';
string2Folded[string2Length] = '\0';
if (params[arg_numbytes] > 0)
{
return static_cast<cell>(strncmp(string1Folded, string2Folded, params[arg_numbytes]) == 0);
}
do
else
{
f = tolower(*a++);
l = tolower(*b++);
} while (f && f == l);
return (f - l) ? 0 : 1;
return static_cast<cell>(strcmp(string1Folded, string2Folded) == 0);
}
}
static cell g_cpbuf[4096];
@ -730,6 +770,29 @@ static cell AMX_NATIVE_CALL strtolower(AMX *amx, cell *params) /* 1 param */
return cptr - begin;
}
// native mb_strtolower(source[], maxlength = 0);
static cell AMX_NATIVE_CALL mb_strtolower(AMX *amx, cell *params)
{
enum args { arg_count, arg_string, arg_maxlength };
auto sourceLength = 0;
auto source = get_amxstring(amx, params[arg_string], 0, sourceLength);
auto outputMaxLength = params[arg_maxlength];
if (outputMaxLength <= 0)
{
outputMaxLength = sourceLength;
}
auto output = get_amxbuffer(1);
auto outputLength = utf8tolower(source, sourceLength, output, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
output[outputLength] = '\0';
return set_amxstring_utf8(amx, params[arg_string], output, outputLength, outputMaxLength);
}
static cell AMX_NATIVE_CALL strtoupper(AMX *amx, cell *params) /* 1 param */
{
cell *cptr = get_amxaddr(amx, params[1]);
@ -744,6 +807,29 @@ static cell AMX_NATIVE_CALL strtoupper(AMX *amx, cell *params) /* 1 param */
return cptr - begin;
}
// native mb_strtoupper(source[], maxlength = 0);
static cell AMX_NATIVE_CALL mb_strtoupper(AMX *amx, cell *params)
{
enum args { arg_count, arg_string, arg_maxlength };
auto sourceLength = 0;
auto source = get_amxstring(amx, params[arg_string], 0, sourceLength);
auto outputMaxLength = params[arg_maxlength];
if (outputMaxLength <= 0)
{
outputMaxLength = sourceLength;
}
auto output = get_amxbuffer(1);
auto outputLength = utf8toupper(source, sourceLength, output, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
output[outputLength] = '\0';
return set_amxstring_utf8(amx, params[arg_string], output, outputLength, outputMaxLength);
}
int fo_numargs(AMX *amx)
{
unsigned char *data = amx->base + (int)((AMX_HEADER *)amx->base)->dat;
@ -843,6 +929,7 @@ static cell AMX_NATIVE_CALL amx_strtok(AMX *amx, cell *params)
int right_pos = 0;
unsigned int i = 0;
bool done_flag = false;
size_t spaces;
int len = 0;
//string[]
@ -862,9 +949,9 @@ static cell AMX_NATIVE_CALL amx_strtok(AMX *amx, cell *params)
{
if (trim && !done_flag)
{
if (isspace(string[i]))
if ((spaces = utf8getspaces(string + i) > 0))
{
while (isspace(string[++i]));
i += spaces;
done_flag = true;
}
}
@ -898,6 +985,7 @@ static cell AMX_NATIVE_CALL amx_strtok2(AMX *amx, cell *params)
{
int left_pos = 0, right_pos = 0, len, pos = -1;
unsigned int i = 0;
size_t spaces;
char *string = get_amxstring(amx, params[1], 0, len);
char *left = new char[len + 1], *right = new char[len + 1];
@ -913,9 +1001,9 @@ static cell AMX_NATIVE_CALL amx_strtok2(AMX *amx, cell *params)
int trim = params[7];
// ltrim left
if (trim & 1 && isspace(string[i]))
if (trim & 1 && (spaces = utf8getspaces(string)) > 0)
{
while (isspace(string[++i]));
i += spaces;
}
for (; i < (unsigned int) len; ++i)
@ -931,17 +1019,17 @@ static cell AMX_NATIVE_CALL amx_strtok2(AMX *amx, cell *params)
}
// rtrim left
if (trim & 2 && left_pos && isspace(left[left_pos - 1]))
if (trim & 2 && left_pos && utf8isspace(&left[left_pos - 1]))
{
while (--left_pos >= 0 && isspace(left[left_pos]));
while (--left_pos >= 0 && utf8isspace(&left[left_pos]));
++left_pos;
}
// ltrim right
if (trim & 4 && isspace(string[i]))
if (trim & 4 && (spaces = utf8getspaces(string + i)) > 0)
{
while (isspace(string[++i]));
i += spaces;
}
for (; i < (unsigned int) len; ++i)
@ -950,9 +1038,9 @@ static cell AMX_NATIVE_CALL amx_strtok2(AMX *amx, cell *params)
}
// rtrim right
if (trim & 8 && right_pos && isspace(right[right_pos - 1]))
if (trim & 8 && right_pos && utf8isspace(&right[right_pos - 1]))
{
while (--right_pos >= 0 && isspace(right[right_pos]));
while (--right_pos >= 0 && utf8isspace(&right[right_pos]));
++right_pos;
}
@ -982,8 +1070,12 @@ static cell AMX_NATIVE_CALL argparse(AMX *amx, cell *params)
// Strip all left-hand whitespace.
size_t i = start_pos;
while (i < input_len && isspace(input[i]))
i++;
size_t spaces;
if ((spaces = utf8getspaces(input + i)) > 0)
{
i += spaces;
}
if (i >= input_len) {
*buffer = '\0';
@ -1002,7 +1094,7 @@ static cell AMX_NATIVE_CALL argparse(AMX *amx, cell *params)
}
// If not in quotes, and we see a space, stop.
if (isspace(input[i]) && !in_quote)
if (utf8isspace(input + i) && !in_quote)
break;
if (size_t(bufpos - buffer) < buflen)
@ -1030,9 +1122,13 @@ static cell AMX_NATIVE_CALL strbreak(AMX *amx, cell *params) /* 5 param */
int RightMax = params[5];
size_t len = (size_t)_len;
size_t spaces;
if ((spaces = utf8getspaces(string)) > 0)
{
i += spaces;
}
while (isspace(string[i]) && i<len)
i++;
beg = i;
for (; i<len; i++)
{
@ -1044,12 +1140,12 @@ static cell AMX_NATIVE_CALL strbreak(AMX *amx, cell *params) /* 5 param */
if (i == len-1)
goto do_copy;
} else {
if (isspace(string[i]) && !in_quote)
if (!in_quote && (spaces = utf8getspaces(string + i)) > 0)
{
do_copy:
size_t pos = i;
while (isspace(string[i]))
i++;
i += spaces;
const char *start = had_quotes ? &(string[beg+1]) : &(string[beg]);
size_t _end = had_quotes ? (i==len-1 ? 1 : 2) : 0;
size_t end = (pos - _end > (size_t)LeftMax) ? (size_t)LeftMax : pos - _end;
@ -1241,6 +1337,46 @@ static cell AMX_NATIVE_CALL amx_ucfirst(AMX *amx, cell *params)
return 1;
}
// native mb_ucfirst(string[], maxlength = 0);
static cell AMX_NATIVE_CALL mb_ucfirst(AMX *amx, cell *params)
{
enum args { arg_count, arg_string, arg_maxlength };
auto sourceLength = 0;
auto source = get_amxstring(amx, params[arg_string], 0, sourceLength);
auto outputMaxLength = params[arg_maxlength];
if (outputMaxLength <= 0)
{
outputMaxLength = sourceLength;
}
// Retrieves the first character length in bytes.
auto firstChLength = utf8seek(source, sourceLength, source, 1, SEEK_CUR) - source;
if (firstChLength)
{
char output[8] = {};
auto outputLength = utf8toupper(source, firstChLength, output, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
// The converted character is either larger or smaller in bytes.
if (firstChLength != outputLength)
{
// Calculates the new string length and makes sure we don't go over the buffer size (fairly unlikely).
sourceLength = ke::Min<int>(sourceLength + (outputLength - firstChLength), outputMaxLength);
// Move data forward or backward minus the first character (whathever its size).
memmove(source + outputLength, source + firstChLength, (sourceLength - outputLength) * sizeof(char));
}
// Copy the new character at the start of the string.
memcpy(source, output, outputLength);
}
return set_amxstring_utf8(amx, params[arg_string], source, sourceLength, outputMaxLength);
}
static cell AMX_NATIVE_CALL amx_strlen(AMX *amx, cell *params)
{
int len;
@ -1251,18 +1387,27 @@ static cell AMX_NATIVE_CALL amx_strlen(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL amx_trim(AMX *amx, cell *params)
{
int len, newlen;
char *str = get_amxstring(amx, params[1], 0, len);
int length;
auto string = get_amxstring(amx, params[1], 0, length);
UTIL_TrimLeft(str);
UTIL_TrimRight(str);
auto leftSpaces = utf8getspaces(string);
auto rightSpaces = 0u;
newlen = strlen(str);
len -= newlen;
auto originalLength = length;
set_amxstring(amx, params[1], str, newlen);
if (leftSpaces < size_t(length))
{
while (--length >= 0 && utf8isspace(string + length))
{
++rightSpaces;
}
}
return len;
auto totalSpaces = leftSpaces + rightSpaces;
set_amxstring(amx, params[1], string + leftSpaces, originalLength - totalSpaces);
return totalSpaces;
}
static cell AMX_NATIVE_CALL n_strcat(AMX *amx, cell *params)
@ -1292,62 +1437,105 @@ static cell AMX_NATIVE_CALL n_strcat(AMX *amx, cell *params)
return params[3] - num;
}
// native strcmp(const string1[], const string2[], bool:ignorecase = false);
static cell AMX_NATIVE_CALL n_strcmp(AMX *amx, cell *params)
{
int len;
char *str1 = get_amxstring(amx, params[1], 0, len);
char *str2 = get_amxstring(amx, params[2], 1, len);
enum args { arg_count, arg_string1, arg_string2, arg_ignorecase };
if (params[3])
return stricmp(str1, str2);
else
return strcmp(str1, str2);
auto string1Length = 0;
auto string2Length = 0;
auto string1 = get_amxstring(amx, params[arg_string1], 0, string1Length);
auto string2 = get_amxstring(amx, params[arg_string2], 1, string2Length);
if (params[arg_ignorecase] != 0)
{
auto string1Folded = get_amxbuffer(2);
auto string2Folded = get_amxbuffer(3);
string1Length = utf8casefold(string1, string1Length, string1Folded, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
string2Length = utf8casefold(string2, string2Length, string2Folded, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
string1Folded[string1Length] = '\0';
string2Folded[string2Length] = '\0';
string1 = string1Folded;
string2 = string2Folded;
}
return strcmp(string1, string2);
}
// native strncmp(const string1[], const string2[], num, bool:ignorecase = false);
static cell AMX_NATIVE_CALL n_strncmp(AMX *amx, cell *params)
{
int len;
char *str1 = get_amxstring(amx, params[1], 0, len);
char *str2 = get_amxstring(amx, params[2], 1, len);
enum args { arg_count, arg_string1, arg_string2, arg_numbytes, arg_ignorecase };
if (params[4])
return strncasecmp(str1, str2, (size_t)params[3]);
else
return strncmp(str1, str2, (size_t)params[3]);
auto string1Length = 0;
auto string2Length = 0;
auto string1 = get_amxstring(amx, params[arg_string1], 0, string1Length);
auto string2 = get_amxstring(amx, params[arg_string2], 1, string2Length);
if (params[arg_ignorecase] != 0)
{
auto string1Folded = get_amxbuffer(2);
auto string2Folded = get_amxbuffer(3);
string1Length = utf8casefold(string1, string1Length, string1Folded, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
string2Length = utf8casefold(string2, string2Length, string2Folded, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
string1Folded[string1Length] = '\0';
string2Folded[string2Length] = '\0';
string1 = string1Folded;
string2 = string2Folded;
}
return strncmp(string1, string2, params[arg_numbytes]);
}
// native strfind(const string[], const sub[], bool:ignorecase = false, pos = 0);
static cell AMX_NATIVE_CALL n_strfind(AMX *amx, cell *params)
{
int len;
char *str = get_amxstring(amx, params[1], 0, len);
int sublen;
char *sub = get_amxstring(amx, params[2], 1, sublen);
enum args { arg_count, arg_source, arg_search, arg_ignorecase, arg_startpos };
bool igcase = params[3] ? true : false;
auto sourceLength = 0;
auto searchLength = 0;
if (igcase)
auto source = get_amxstring(amx, params[arg_source], 0, sourceLength);
auto search = get_amxstring(amx, params[arg_search], 1, searchLength);
if (params[arg_ignorecase] != 0)
{
for (int i = 0; i < len; i++)
{
if (str[i] & (1<<5))
str[i] &= ~(1<<5);
}
for (int i = 0; i < sublen; i++)
{
if (str[i] & (1<<5))
str[i] &= ~(1<<5);
}
auto sourceFolded = get_amxbuffer(2);
auto searchFolded = get_amxbuffer(3);
sourceLength = utf8casefold(source, sourceLength, sourceFolded, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
searchLength = utf8casefold(search, searchLength, searchFolded, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
sourceFolded[sourceLength] = '\0';
searchFolded[searchLength] = '\0';
source = sourceFolded;
search = searchFolded;
}
if (params[4] > len)
auto position = params[arg_startpos];
if (position < 0 || position > sourceLength)
{
return -1;
}
char *find = strstr(str + params[4], sub);
auto find = strstr(source + position, search);
if (!find)
{
return -1;
}
return (find - str);
return (find - source);
}
static cell AMX_NATIVE_CALL vformat(AMX *amx, cell *params)
@ -1424,6 +1612,60 @@ static cell AMX_NATIVE_CALL fmt(AMX *amx, cell *params)
return 1;
};
// native mb_strtotitle(source[], maxlength = 0);
static cell AMX_NATIVE_CALL mb_strtotitle(AMX *amx, cell *params)
{
enum args { arg_count, arg_string, arg_maxlength };
auto sourceLength = 0;
auto source = get_amxstring(amx, params[arg_string], 0, sourceLength);
auto outputMaxLength = params[arg_maxlength];
if (outputMaxLength <= 0)
{
outputMaxLength = sourceLength;
}
auto output = get_amxbuffer(1);
auto outputLength = utf8totitle(source, sourceLength, output, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
output[outputLength] = '\0';
return set_amxstring_utf8(amx, params[arg_string], output, outputLength, outputMaxLength);
}
// native bool:is_string_category(const input[], input_size, flags, &output_size = 0);
static cell AMX_NATIVE_CALL is_string_category(AMX *amx, cell *params)
{
enum args { arg_count, arg_input, arg_inputsize, arg_flags, arg_outputsize };
auto inputLength = 0;
auto input = get_amxstring(amx, params[arg_input], 0, inputLength);
auto inputMaxLength = ke::Min(params[arg_inputsize], inputLength);
auto outputSize = get_amxaddr(amx, params[arg_outputsize]);
// User wants to check only one character whatever its size.
if (inputMaxLength <= 1)
{
// Gets the character length.
inputMaxLength = utf8seek(input, inputLength, input, 1, SEEK_CUR) - input;
// Truncated character.
if (inputMaxLength > inputLength)
{
*outputSize = 0;
return FALSE;
}
}
// Checks input with the given flags.
*outputSize = utf8iscategory(input, inputMaxLength, params[arg_flags]);
// If function consumed input, then it's a success.
return static_cast<cell>(*outputSize == inputMaxLength);
}
AMX_NATIVE_INFO string_Natives[] =
{
@ -1445,7 +1687,12 @@ AMX_NATIVE_INFO string_Natives[] =
{"is_char_upper", is_char_upper},
{"is_char_lower", is_char_lower},
{"is_char_mb", is_char_mb},
{"is_string_category", is_string_category },
{"get_char_bytes", get_char_bytes},
{"mb_strtotitle", mb_strtotitle},
{"mb_strtolower", mb_strtolower},
{"mb_strtoupper", mb_strtoupper},
{"mb_ucfirst", mb_ucfirst},
{"num_to_str", numtostr},
{"numtostr", numtostr},
{"parse", parse},

View File

@ -44,7 +44,12 @@ cell destroyParser(cell *handle)
// native SMCParser:SMC_CreateParser();
static cell AMX_NATIVE_CALL SMC_CreateParser(AMX *amx, cell *params)
{
return createParser();
const auto handle = createParser();
const auto parseInfo = TextParsersHandles.lookup(handle);
parseInfo->handle = handle;
return handle;
}
// native SMC_SetParseStart(SMCParser:handle, const func[]);
@ -224,7 +229,12 @@ static cell AMX_NATIVE_CALL SMC_DestroyParser(AMX *amx, cell *params)
// native INIParser:INI_CreateParser();
static cell AMX_NATIVE_CALL INI_CreateParser(AMX *amx, cell *params)
{
return createParser();
const auto handle = createParser();
const auto parseInfo = TextParsersHandles.lookup(handle);
parseInfo->handle = handle;
return handle;
}
// native bool:INI_ParseFile(INIParser:handle, const file[], &line = 0, &col = 0, any:data = 0);

View File

@ -10,6 +10,7 @@
#include "trie_natives.h"
NativeHandle<CellTrie> TrieHandles;
NativeHandle<CellTrieIter> TrieIterHandles;
NativeHandle<TrieSnapshot> TrieSnapshotHandles;
// native Trie:TrieCreate();
@ -344,6 +345,18 @@ static cell AMX_NATIVE_CALL TrieDestroy(AMX *amx, cell *params)
return 0;
}
CellTrieIter *iter;
for (size_t index = 1; index <= TrieIterHandles.size(); index++)
{
if ((iter = TrieIterHandles.lookup(index)))
{
if (iter->trie == t)
{
iter->trie = nullptr;
}
}
}
if (TrieHandles.destroy(*ptr))
{
*ptr = 0;
@ -469,6 +482,226 @@ static cell AMX_NATIVE_CALL TrieSnapshotDestroy(AMX *amx, cell *params)
return 0;
}
#define CHECK_ITER_HANDLE(handle) \
if (!handle) { \
LogError(amx, AMX_ERR_NATIVE, "Invalid map iterator handle provided (%d)", params[arg_handle]); \
return 0; \
} \
if (!handle->trie) { \
LogError(amx, AMX_ERR_NATIVE, "Closed map iterator handle provided (%d)", params[arg_handle]); \
return 0; \
} \
if (handle->mod_count != handle->trie->map.mod_count()) { \
LogError(amx, AMX_ERR_NATIVE, "Outdated map iterator handle provided (%d)", params[arg_handle]);\
return 0; \
}
// native TrieIter:TrieIterCreate(Trie:handle)
static cell AMX_NATIVE_CALL TrieIterCreate(AMX *amx, cell *params)
{
enum args { arg_count, arg_handle };
auto handle = TrieHandles.lookup(params[arg_handle]);
if (!handle)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid map handle provided (%d)", params[arg_handle]);
return 0;
}
auto index = TrieIterHandles.create(handle);
auto iter = TrieIterHandles.lookup(index);
return static_cast<cell>(index);
}
// native bool:TrieIterEnded(TrieIter:handle)
static cell AMX_NATIVE_CALL TrieIterEnded(AMX *amx, cell *params)
{
enum args { arg_count, arg_handle };
auto handle = TrieIterHandles.lookup(params[arg_handle]);
CHECK_ITER_HANDLE(handle)
return handle->iter.empty();
}
// native TrieIterNext(TrieIter:handle)
static cell AMX_NATIVE_CALL TrieIterNext(AMX *amx, cell *params)
{
enum args { arg_count, arg_handle };
auto handle = TrieIterHandles.lookup(params[arg_handle]);
CHECK_ITER_HANDLE(handle)
if (handle->iter.empty())
{
return 0;
}
handle->iter.next();
return 1;
}
// native TrieIterGetKey(TrieIter:handle, key[], outputsize)
static cell AMX_NATIVE_CALL TrieIterGetKey(AMX *amx, cell *params)
{
enum args { arg_count, arg_handle, arg_output, arg_outputsize };
auto handle = TrieIterHandles.lookup(params[arg_handle]);
CHECK_ITER_HANDLE(handle)
auto& iter = handle->iter;
if (iter.empty())
{
*get_amxaddr(amx, params[arg_output]) = '\0';
return 0;
}
return set_amxstring_utf8(amx, params[arg_output], iter->key.chars(), iter->key.length(), params[arg_outputsize]);
}
// native TrieIterGetSize(TrieIter:handle)
static cell AMX_NATIVE_CALL TrieIterGetSize(AMX *amx, cell *params)
{
enum args { arg_count, arg_handle };
auto handle = TrieIterHandles.lookup(params[arg_handle]);
CHECK_ITER_HANDLE(handle)
return handle->trie->map.elements();
}
// native bool:TrieIterGetCell(TrieIter:handle, &any:value)
static cell AMX_NATIVE_CALL TrieIterGetCell(AMX *amx, cell *params)
{
enum args { arg_count, arg_handle, arg_outputvalue };
auto handle = TrieIterHandles.lookup(params[arg_handle]);
CHECK_ITER_HANDLE(handle)
auto& iter = handle->iter;
if (iter.empty() || !iter->value.isCell())
{
return false;
}
*get_amxaddr(amx, params[arg_outputvalue]) = iter->value.cell_();
return true;
}
// native bool:TrieIterGetString(TrieIter:handle, buffer[], outputsize, &size = 0)
static cell AMX_NATIVE_CALL TrieIterGetString(AMX *amx, cell *params)
{
enum args { arg_count, arg_handle, arg_output, arg_outputsize, arg_refsize };
auto handle = TrieIterHandles.lookup(params[arg_handle]);
CHECK_ITER_HANDLE(handle)
if (params[arg_outputsize] < 0)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid buffer size (%d)", params[arg_outputsize]);
return 0;
}
auto& iter = handle->iter;
if (iter.empty() || !iter->value.isString())
{
return false;
}
auto refsize = get_amxaddr(amx, params[arg_refsize]);
*refsize = set_amxstring_utf8(amx, params[arg_output], iter->value.chars(), strlen(iter->value.chars()), params[arg_outputsize]);
return true;
}
// native bool:TrieIterGetArray(TrieIter:handle, array[], outputsize, &size = 0)
static cell AMX_NATIVE_CALL TrieIterGetArray(AMX *amx, cell *params)
{
enum args { arg_count, arg_handle, arg_output, arg_outputsize, arg_refsize };
auto handle = TrieIterHandles.lookup(params[arg_handle]);
CHECK_ITER_HANDLE(handle)
auto outputSize = params[arg_outputsize];
if (outputSize < 0)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid array size (%d)", params[arg_outputsize]);
return 0;
}
auto& iter = handle->iter;
if (iter.empty() || !iter->value.isArray())
{
return false;
}
auto pOutput = get_amxaddr(amx, params[arg_output]);
auto pSize = get_amxaddr(amx, params[arg_refsize]);
if (!iter->value.array() || !outputSize)
{
*pSize = 0;
return false;
}
auto length = iter->value.arrayLength();
auto base = iter->value.array();
if (length > size_t(outputSize))
{
length = outputSize;
}
*pSize = length;
memcpy(pOutput, base, sizeof(cell) * length);
return true;
}
// native TrieIterDestroy(&TrieIter:handle)
static cell AMX_NATIVE_CALL TrieIterDestroy(AMX *amx, cell *params)
{
enum args { arg_count, arg_handle };
auto refhandle = get_amxaddr(amx, params[arg_handle]);
auto handle = TrieIterHandles.lookup(*refhandle);
if (!handle)
{
return false;
}
handle->trie = nullptr;
if (TrieIterHandles.destroy(*refhandle))
{
*refhandle = 0;
return true;
}
return false;
}
AMX_NATIVE_INFO trie_Natives[] =
{
{ "TrieCreate" , TrieCreate },
@ -493,6 +726,16 @@ AMX_NATIVE_INFO trie_Natives[] =
{ "TrieSnapshotGetKey" , TrieSnapshotGetKey },
{ "TrieSnapshotDestroy" , TrieSnapshotDestroy },
{ "TrieIterCreate" , TrieIterCreate },
{ "TrieIterEnded" , TrieIterEnded },
{ "TrieIterNext" , TrieIterNext },
{ "TrieIterGetKey" , TrieIterGetKey },
{ "TrieIterGetSize" , TrieIterGetSize },
{ "TrieIterGetCell" , TrieIterGetCell },
{ "TrieIterGetString" , TrieIterGetString },
{ "TrieIterGetArray" , TrieIterGetArray },
{ "TrieIterDestroy" , TrieIterDestroy },
{ nullptr , nullptr}
};

View File

@ -14,6 +14,7 @@
#include <sm_stringhashmap.h>
#include <sm_memtable.h>
#include "natives_handles.h"
#include <amtl/am-uniqueptr.h>
enum EntryType
{
@ -138,9 +139,128 @@ private:
cell data_;
};
template <typename T>
class StringHashMapCustom
{
typedef StringHashMap<T> Internal;
public:
StringHashMapCustom() : mod_count_(0)
{}
public:
typedef typename Internal::Result Result;
typedef typename Internal::Insert Insert;
typedef typename Internal::iterator iterator;
public:
size_t elements() const
{
return internal_.elements();
}
iterator iter()
{
return internal_.iter();
}
bool contains(const char *aKey)
{
return internal_.contains(aKey);
}
bool replace(const char *aKey, const T &value)
{
return internal_.contains(aKey, value);
}
bool insert(const char *aKey, const T &value)
{
if (internal_.insert(aKey, value))
{
mod_count_++;
return true;
}
return false;
}
bool remove(const char *aKey)
{
if (internal_.remove(aKey))
{
mod_count_++;
return true;
}
return false;
}
void clear()
{
mod_count_++;
internal_.clear();
}
void remove(Result &r)
{
mod_count_++;
internal_.remove(r);
}
Result find(const char *aKey)
{
return internal_.find(aKey);
}
Insert findForAdd(const char *aKey)
{
return internal_.findForAdd(aKey);
}
bool add(Insert &i, const char *aKey)
{
if (internal_.add(i, aKey))
{
mod_count_++;
return true;
}
return false;
}
bool add(Insert &i)
{
if (internal_.add(i))
{
mod_count_++;
return true;
}
return false;
}
public:
size_t mod_count() const
{
return mod_count_;
}
private:
Internal internal_;
size_t mod_count_;
};
struct CellTrie
{
StringHashMap<Entry> map;
StringHashMapCustom<Entry> map;
};
struct CellTrieIter
{
CellTrieIter(CellTrie *_trie) : trie(_trie), iter(_trie->map.iter()), mod_count(_trie->map.mod_count())
{}
CellTrie *trie;
StringHashMapCustom<Entry>::iterator iter;
size_t mod_count;
};
struct TrieSnapshot
@ -160,6 +280,7 @@ struct TrieSnapshot
};
extern NativeHandle<CellTrie> TrieHandles;
extern NativeHandle<CellTrieIter> TrieIterHandles;
extern NativeHandle<TrieSnapshot> TrieSnapshotHandles;
extern AMX_NATIVE_INFO trie_Natives[];

View File

@ -9,6 +9,7 @@
#include <time.h>
#include "amxmodx.h"
#include <utf8rewind.h>
int UTIL_ReadFlags(const char* c)
{
@ -372,8 +373,8 @@ void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1,
{
if ((*aa).matchCommandLine(cmd, arg1) && (*aa).getPlugin()->isExecutable((*aa).getFunction()))
{
if (executeForwards((*aa).getFunction(), static_cast<cell>(GET_PLAYER_POINTER(pEdict)->index)),
static_cast<cell>((*aa).getFlags()), static_cast<cell>((*aa).getId()) > 0)
if (executeForwards((*aa).getFunction(), static_cast<cell>(GET_PLAYER_POINTER(pEdict)->index),
static_cast<cell>((*aa).getFlags()), static_cast<cell>((*aa).getId())) > 0)
{
g_fakecmd.notify = false;
return;
@ -454,11 +455,38 @@ int UTIL_CheckValidChar(D *c)
return 0;
}
unsigned int UTIL_ReplaceAll(char *subject, size_t maxlength, const char *search, const char *replace, bool caseSensitive)
{
size_t searchLen = strlen(search);
size_t replaceLen = strlen(replace);
static char OutputBuffer1[MAX_BUFFER_LENGTH];
static char OutputBuffer2[MAX_BUFFER_LENGTH];
char* utf8stristr(const char *string1, const char *string2)
{
auto string1Length = utf8casefold(string1, strlen(string1), OutputBuffer1, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
auto string2Length = utf8casefold(string2, strlen(string2), OutputBuffer2, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
OutputBuffer1[string1Length] = '\0';
OutputBuffer2[string2Length] = '\0';
return strstr(OutputBuffer1, OutputBuffer2);
}
int utf8strncasecmp(const char *string1, const char *string2, size_t n)
{
auto string1Length = utf8casefold(string1, strlen(string1), OutputBuffer1, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
auto string2Length = utf8casefold(string2, strlen(string2), OutputBuffer2, MAX_BUFFER_LENGTH - 1, UTF8_LOCALE_DEFAULT, nullptr, TRUE);
OutputBuffer1[string1Length] = '\0';
OutputBuffer2[string2Length] = '\0';
return n != 0 ? strncmp(OutputBuffer1, OutputBuffer2, n) : strcmp(OutputBuffer1, OutputBuffer2);
}
int utf8strcasecmp(const char *string1, const char *string2)
{
return utf8strncasecmp(string1, string2, 0);
}
size_t UTIL_ReplaceAll(char *subject, size_t maxlength, const char *search, size_t searchLen, const char *replace, size_t replaceLen, bool caseSensitive)
{
char *newptr, *ptr = subject;
unsigned int total = 0;
while ((newptr = UTIL_ReplaceEx(ptr, maxlength, search, searchLen, replace, replaceLen, caseSensitive)) != NULL)
@ -476,9 +504,15 @@ unsigned int UTIL_ReplaceAll(char *subject, size_t maxlength, const char *search
return total;
}
template unsigned int strncopy<char, char>(char *, const char *src, size_t count);
template unsigned int strncopy<cell, char>(cell *, const char *src, size_t count);
template unsigned int strncopy<cell, cell>(cell *, const cell *src, size_t count);
size_t UTIL_ReplaceAll(char *subject, size_t maxlength, const char *search, const char *replace, bool caseSensitive)
{
return UTIL_ReplaceAll(subject, maxlength, search, strlen(search), replace, strlen(replace), caseSensitive);
}
template unsigned int strncopy<char, char>(char *, const char *, size_t);
template unsigned int strncopy<char, cell>(char *, const cell *, size_t);
template unsigned int strncopy<cell, char>(cell *, const char *, size_t);
template unsigned int strncopy<cell, cell>(cell *, const cell *, size_t);
template <typename D, typename S>
unsigned int strncopy(D *dest, const S *src, size_t count)
@ -533,7 +567,7 @@ char *UTIL_ReplaceEx(char *subject, size_t maxLen, const char *search, size_t se
/* If the search matches and the replace length is 0,
* we can just terminate the string and be done.
*/
if ((caseSensitive ? strcmp(subject, search) : strcasecmp(subject, search)) == 0 && replaceLen == 0)
if ((caseSensitive ? strcmp(subject, search) : utf8strcasecmp(subject, search)) == 0 && replaceLen == 0)
{
*subject = '\0';
return subject;
@ -550,7 +584,7 @@ char *UTIL_ReplaceEx(char *subject, size_t maxLen, const char *search, size_t se
while (*ptr != '\0' && (browsed <= textLen - searchLen))
{
/* See if we get a comparison */
if ((caseSensitive ? strncmp(ptr, search, searchLen) : strncasecmp(ptr, search, searchLen)) == 0)
if ((caseSensitive ? strncmp(ptr, search, searchLen) : utf8strncasecmp(ptr, search, searchLen)) == 0)
{
if (replaceLen > searchLen)
{

View File

@ -6,13 +6,7 @@
// Generated from the TEXTINCLUDE 2 resource.
//
#include <winresrc.h>
#if defined AMBUILD
# include <amxmodx_version.h>
#else
# define SVN_VERSION_DWORD 1, 8, 3, 0
# define SVN_VERSION_STRING "dev-local"
# define SVN_VERSION SVN_VERSION_STRING
#endif
#include <amxmodx_version.h>
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
@ -32,8 +26,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION SVN_VERSION_DWORD
PRODUCTVERSION SVN_VERSION_DWORD
FILEVERSION AMXX_VERSION_FILE
PRODUCTVERSION AMXX_VERSION_FILE
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -50,12 +44,12 @@ BEGIN
BEGIN
VALUE "Comments", "AMX Mod X"
VALUE "FileDescription", "AMX Mod X"
VALUE "FileVersion", SVN_VERSION_STRING
VALUE "FileVersion", AMXX_VERSION_STRING
VALUE "InternalName", "amxmodx"
VALUE "LegalCopyright", "Copyright (c) 2004-2015, AMX Mod X Dev Team"
VALUE "OriginalFilename", "amxmodx_mm.dll"
VALUE "ProductName", "AMX Mod X"
VALUE "ProductVersion", SVN_VERSION
VALUE "ProductVersion", AMXX_VERSION_STRING
END
END
BLOCK "VarFileInfo"

View File

@ -3,16 +3,30 @@ clone_folder: c:\projects\amxmodx
install:
- git submodule update --init --recursive
- 'c:'
- mkdir c:\nasm
- set PATH=c:\nasm\nasm-2.13.03;%PATH%
- curl -L -o "c:\nasm\nasm.zip" https://www.nasm.us/pub/nasm/releasebuilds/2.13.03/win32/nasm-2.13.03-win32.zip
- chdir c:\nasm
- 7z x nasm.zip
- chdir c:\projects
- git clone https://github.com/alliedmodders/ambuild
- git clone https://github.com/alliedmodders/metamod-hl1
- git clone https://github.com/alliedmodders/hlsdk
- cd ambuild
- ps: Start-FileDownload 'https://downloads.mysql.com/archives/get/file/mysql-connector-c-6.1.1-win32.zip'
- 7z x mysql-connector-c-6.1.1-win32.zip -o"mysql"
- cd mysql
- dir
- ren mysql-connector-c-6.1.1-win32 mysql-5.5
- move /Y mysql-5.5 ..\
- cd ..\ambuild
- c:\python27\python setup.py install
- cd ..\amxmodx
cache:
- c:\projects\*.zip -> appveyor.yml
- c:\projects\mysql-5.5 -> appveyor.yml
build_script:
- '"%VS120COMNTOOLS%\vsvars32.bat"'
- '"%VS140COMNTOOLS%\vsvars32.bat"'
- mkdir build
- cd build
- c:\python27\python ../configure.py --enable-optimize --no-mysql
- c:\python27\python ../configure.py --enable-optimize --nasm="C:\nasm\nasm-2.13.03\nasm.exe"
- c:\python27\scripts\ambuild

View File

@ -65,7 +65,7 @@ int main(int argc, char **argv)
# else
printf("compiler failed to instantiate: %d\n", GetLastError());
# endif
exit(0);
exit(EXIT_FAILURE);
}
COMPILER sc32 = (COMPILER)dlsym(lib, "Compile32");
@ -79,7 +79,7 @@ int main(int argc, char **argv)
#else
printf("compiler failed to link: %d.\n", GetLastError());
#endif
exit(0);
exit(EXIT_FAILURE);
}
pc_printf("AMX Mod X Compiler %s\n", AMXX_VERSION);
@ -91,7 +91,7 @@ int main(int argc, char **argv)
pc_printf("Usage: <file.sma> [options]\n");
pc_printf("Use -? or --help to see full options\n\n");
getchar();
exit(0);
exit(EXIT_FAILURE);
}
if (!strcmp(argv[1], "-?") || !strcmp(argv[1], "--help"))
@ -99,7 +99,7 @@ int main(int argc, char **argv)
show_help();
pc_printf("Press any key to continue.\n");
getchar();
exit(0);
exit(EXIT_SUCCESS);
}
sc32(argc, argv);
@ -109,16 +109,16 @@ int main(int argc, char **argv)
if (file == NULL)
{
pc_printf("Could not locate the output file.\n");
exit(0);
exit(EXIT_FAILURE);
} else if (strstr(file, ".asm")) {
pc_printf("Assembler output succeeded.\n");
exit(0);
exit(EXIT_SUCCESS);
} else {
FILE *fp = fopen(file, "rb");
if (fp == NULL)
{
pc_printf("Could not locate output file %s (compile failed).\n", file);
exit(0);
exit(EXIT_FAILURE);
}
ReadFileIntoPl(&pl32, fp);
pl32.cellsize = 4;
@ -142,7 +142,7 @@ int main(int argc, char **argv)
if (!fp)
{
pc_printf("Error trying to write file %s.\n", newfile);
exit(0);
exit(EXIT_FAILURE);
}
BinPlugin bh32;
@ -179,7 +179,7 @@ int main(int argc, char **argv)
#if !defined EMSCRIPTEN
dlclose(lib);
#endif
exit(0);
exit(EXIT_FAILURE);
}
fclose(fp);
@ -195,7 +195,7 @@ int main(int argc, char **argv)
dlclose(lib);
#endif
exit(0);
exit(EXIT_SUCCESS);
}
void WriteBh(BinaryWriter *bw, BinPlugin *bh)
@ -228,7 +228,7 @@ bool CompressPl(abl *pl)
if (err != Z_OK)
{
pc_printf("internal error - compression failed on first pass: %d\n", err);
exit(0);
exit(EXIT_FAILURE);
}
return true;

View File

@ -55,29 +55,28 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE; AMX_ANSIONLY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_MBCS;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE; AMX_ANSIONLY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>..\..\public;..\..\third_party;..\..\third_party\zlib;..\..\amxmodx\;C:\Program Files (x86)\Visual Leak Detector\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)amxxpc.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
<IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<IgnoreSpecificDefaultLibraries>
</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE; AMX_ANSIONLY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_MBCS;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE; AMX_ANSIONLY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<StructMemberAlignment>Default</StructMemberAlignment>
<RuntimeTypeInfo>false</RuntimeTypeInfo>

View File

@ -54,7 +54,7 @@
#define CTRL_CHAR '^' /* default control character */
#define sCHARBITS 8 /* size of a packed character */
#define sDIMEN_MAX 3 /* maximum number of array dimensions */
#define sDIMEN_MAX 4 /* maximum number of array dimensions */
#define sLINEMAX 4095 /* input line length (in characters) */
#define sCOMP_STACK 32 /* maximum nesting of #if .. #endif sections */
#define sDEF_LITMAX 500 /* initial size of the literal pool, in "cells" */
@ -280,6 +280,12 @@ typedef struct s_stringpair {
char *documentation;
} stringpair;
typedef struct s_valuepair {
struct s_valuepair *next;
long first;
long second;
} valuepair;
/* macros for code generation */
#define opcodes(n) ((n)*sizeof(cell)) /* opcode size */
#define opargs(n) ((n)*sizeof(cell)) /* size of typical argument */
@ -521,6 +527,10 @@ SC_FUNC symbol *add_constant(char *name,cell val,int vclass,int tag);
SC_FUNC void exporttag(int tag);
SC_FUNC void sc_attachdocumentation(symbol *sym);
SC_FUNC int get_actual_compound(symbol *sym);
#if !defined NO_DEFINE
SC_FUNC void inst_file_name(char* filename, int strip_path);
#endif
/* function prototypes in SC2.C */
#define PUSHSTK_P(v) { stkitem s_; s_.pv=(v); pushstk(s_); }
@ -696,6 +706,9 @@ SC_FUNC void delete_docstringtable(void);
SC_FUNC stringlist *insert_autolist(char *string);
SC_FUNC char *get_autolist(int index);
SC_FUNC void delete_autolisttable(void);
SC_FUNC valuepair *push_heaplist(long first, long second);
SC_FUNC int popfront_heaplist(long *first, long *second);
SC_FUNC void delete_heaplisttable(void);
SC_FUNC stringlist *insert_dbgfile(const char *filename);
SC_FUNC stringlist *insert_dbgline(int linenr);
SC_FUNC stringlist *insert_dbgsymbol(symbol *sym);
@ -722,8 +735,6 @@ int mfputs(MEMFILE *mf,char *string);
SC_FUNC int cp_path(const char *root,const char *directory);
SC_FUNC int cp_set(const char *name);
SC_FUNC cell cp_translate(const unsigned char *string,const unsigned char **endptr);
SC_FUNC cell get_utf8_char(const unsigned char *string,const unsigned char **endptr);
SC_FUNC int scan_utf8(FILE *fp,const char *filename);
/* function prototypes in SCSTATE.C */
SC_FUNC constvalue *automaton_add(const char *name);
@ -799,7 +810,6 @@ SC_VDECL int sc_status; /* read/write status */
SC_VDECL int sc_rationaltag; /* tag for rational numbers */
SC_VDECL int rational_digits; /* number of fractional digits */
SC_VDECL int sc_allowproccall;/* allow/detect tagnames in lex() */
SC_VDECL short sc_is_utf8; /* is this source file in UTF-8 encoding */
SC_VDECL char *pc_deprecate; /* if non-NULL, mark next declaration as deprecated */
SC_VDECL int sc_warnings_are_errors;

View File

@ -408,11 +408,47 @@ void inst_datetime_defines()
insert_subst("__TIME__", ltime, 8);
}
void inst_file_name(char *file, int strip_path)
{
char newname[_MAX_PATH];
char *fileptr;
fileptr = NULL;
if (strip_path) {
size_t i, len;
int slashchar;
len = strlen(file);
for (i = len - 1; i < len; i--)
{
slashchar = file[i] == '/';
#if defined WIN32 || defined _WIN32
slashchar = slashchar || file[i] == '\\';
#endif
if (slashchar)
{
fileptr = &file[i + 1];
break;
}
}
}
if (fileptr == NULL) {
fileptr = file;
}
snprintf(newname, sizeof(newname), "\"%s\"", fileptr);
insert_subst("__FILE__", newname, 8);
}
static void inst_binary_name(char *binfname)
{
size_t i, len;
char *binptr;
char newpath[512], newname[512];
char newname[_MAX_PATH];
int slashchar;
binptr = NULL;
@ -435,11 +471,9 @@ static void inst_binary_name(char *binfname)
binptr = binfname;
}
snprintf(newpath, sizeof(newpath), "\"%s\"", binfname);
snprintf(newname, sizeof(newname), "\"%s\"", binptr);
insert_subst("__BINARY_PATH__", newpath, 15);
insert_subst("__BINARY_NAME__", newname, 15);
insert_subst("__BINARY__", newname, 10);
}
/* "main" of the compiler
@ -594,10 +628,12 @@ int pc_compile(int argc, char *argv[])
/* reset "defined" flag of all functions and global variables */
reduce_referrers(&glbtab);
delete_symbols(&glbtab,0,TRUE,FALSE);
delete_heaplisttable();
#if !defined NO_DEFINE
delete_substtable();
inst_datetime_defines();
inst_binary_name(binfname);
inst_file_name(inpfname, TRUE);
#endif
resetglobals();
sc_ctrlchar=sc_ctrlchar_org;
@ -663,6 +699,7 @@ int pc_compile(int argc, char *argv[])
delete_substtable();
inst_datetime_defines();
inst_binary_name(binfname);
inst_file_name(inpfname, TRUE);
#endif
resetglobals();
sc_ctrlchar=sc_ctrlchar_org;
@ -769,6 +806,7 @@ cleanup:
free(sc_documentation);
#endif
delete_autolisttable();
delete_heaplisttable();
if (errnum!=0) {
if (strlen(errfname)==0)
pc_printf("\n%d Error%s.\n",errnum,(errnum>1) ? "s" : "");
@ -2134,26 +2172,24 @@ static cell calc_arraysize(int dim[],int numdim,int cur)
return dim[cur]+(dim[cur]*calc_arraysize(dim,numdim,cur+1));
}
static cell adjust_indirectiontables(int dim[],int numdim,int cur,cell increment,
int startlit,constvalue *lastdim,int *skipdim)
static void adjust_indirectiontables(int dim[],int numdim,int startlit,
constvalue *lastdim,int *skipdim)
{
static int base;
int d;
int cur;
int i,d;
cell accum;
cell size;
assert(cur>=0 && cur<numdim);
assert(increment>=0);
assert(cur>0 && startlit==-1 || startlit>=0 && startlit<=litidx);
if (cur==0)
assert(startlit==-1 || startlit>=0 && startlit<=litidx);
base=startlit;
if (cur==numdim-1)
return 0;
size=1;
for (cur=0; cur<numdim-1; cur++) {
/* 2 or more dimensions left, fill in an indirection vector */
assert(dim[cur]>0);
if (dim[cur+1]>0) {
for (i=0; i<size; i++)
for (d=0; d<dim[cur]; d++)
litq[base++]=(dim[cur]+d*(dim[cur+1]-1)+increment) * sizeof(cell);
accum=dim[cur]*(dim[cur+1]-1);
litq[base++]=(size*dim[cur]+(dim[cur+1]-1)*(dim[cur]*i+d)) * sizeof(cell);
} else {
/* final dimension is variable length */
constvalue *ld;
@ -2161,6 +2197,7 @@ static int base;
assert(lastdim!=NULL);
assert(skipdim!=NULL);
accum=0;
for (i=0; i<size; i++) {
/* skip the final dimension sizes for all earlier major dimensions */
for (d=0,ld=lastdim->next; d<*skipdim; d++,ld=ld->next) {
assert(ld!=NULL);
@ -2168,19 +2205,15 @@ static int base;
for (d=0; d<dim[cur]; d++) {
assert(ld!=NULL);
assert(strtol(ld->name,NULL,16)==d);
litq[base++]=(dim[cur]+accum+increment) * sizeof(cell);
litq[base++]=(size*dim[cur]+accum) * sizeof(cell);
accum+=ld->value-1;
*skipdim+=1;
ld=ld->next;
} /* for */
} /* for */
} /* if */
/* create the indirection tables for the lower level */
if (cur+2<numdim) { /* are there at least 2 dimensions below this one? */
increment+=(dim[cur]-1)*dim[cur+1]; /* this many indirection tables follow */
for (d=0; d<dim[cur]; d++)
increment+=adjust_indirectiontables(dim,numdim,cur+1,increment,-1,lastdim,skipdim);
} /* if */
return accum;
size*=dim[cur];
} /* for */
}
/* initials
@ -2238,7 +2271,7 @@ static void initials2(int ident,int tag,cell *size,int dim[],int numdim,
for (tablesize=calc_arraysize(dim,numdim-1,0); tablesize>0; tablesize--)
litadd(0);
if (dim[numdim-1]!=0) /* error 9 has already been given */
adjust_indirectiontables(dim,numdim,0,0,curlit,NULL,NULL);
adjust_indirectiontables(dim,numdim,curlit,NULL,NULL);
} /* if */
return;
} /* if */
@ -2304,7 +2337,7 @@ static void initials2(int ident,int tag,cell *size,int dim[],int numdim,
* of the array and we can properly adjust the indirection vectors
*/
if (err==0)
adjust_indirectiontables(dim,numdim,0,0,curlit,&lastdim,&skipdim);
adjust_indirectiontables(dim,numdim,curlit,&lastdim,&skipdim);
delete_consttable(&lastdim); /* clear list of minor dimension sizes */
} /* if */
} /* if */
@ -5334,7 +5367,7 @@ static void doreturn(void)
/* "return <value>" */
if ((rettype & uRETNONE)!=0)
error(78); /* mix "return;" and "return value;" */
ident=doexpr(TRUE,FALSE,TRUE,TRUE,&tag,&sym,TRUE);
ident=doexpr(TRUE,FALSE,TRUE,FALSE,&tag,&sym,TRUE);
needtoken(tTERM);
if (ident == iARRAY && sym == NULL) {
/* returning a literal string is not supported (it must be a variable) */
@ -5419,6 +5452,16 @@ static void doreturn(void)
/* nothing */;
sub=addvariable(curfunc->name,(argcount+3)*sizeof(cell),iREFARRAY,sGLOBAL,curfunc->tag,dim,numdim,idxtag);
sub->parent=curfunc;
/* Function that returns array can be used before it is defined, so at
* the call point (if it is before definition) we may not know if this
* function returns array and what is its size (for example inside the
* conditional operator), so we don't know how many cells on the heap
* we need. Calculating heap consumption is required for the fix of
* incorrect heap deallocation on conditional operator. That's why we
* need an additional pass.
*/
if ((curfunc->usage & uREAD)!=0)
sc_reparse=TRUE;
} /* if */
/* get the hidden parameter, copy the array (the array is on the heap;
* it stays on the heap for the moment, and it is removed -usually- at
@ -5495,7 +5538,7 @@ static void doexit(void)
int tag=0;
if (matchtoken(tTERM)==0){
doexpr(TRUE,FALSE,FALSE,TRUE,&tag,NULL,TRUE);
doexpr(TRUE,FALSE,FALSE,FALSE,&tag,NULL,TRUE);
needtoken(tTERM);
} else {
ldconst(0,sPRI);
@ -5511,7 +5554,7 @@ static void dosleep(void)
int tag=0;
if (matchtoken(tTERM)==0){
doexpr(TRUE,FALSE,FALSE,TRUE,&tag,NULL,TRUE);
doexpr(TRUE,FALSE,FALSE, FALSE,&tag,NULL,TRUE);
needtoken(tTERM);
} else {
ldconst(0,sPRI);

View File

@ -152,7 +152,6 @@ static char *extensions[] = { ".inc", ".p", ".pawn" };
PUSHSTK_I(iflevel);
assert(!SKIPPING);
assert(skiplevel==iflevel); /* these two are always the same when "parsing" */
PUSHSTK_I(sc_is_utf8);
PUSHSTK_I(icomment);
PUSHSTK_I(fcurrent);
PUSHSTK_I(fline);
@ -169,7 +168,6 @@ static char *extensions[] = { ".inc", ".p", ".pawn" };
assert(sc_status == statFIRST || strcmp(get_inputfile(fcurrent), inpfname) == 0);
setfiledirect(inpfname); /* (optionally) set in the list file */
listline=-1; /* force a #line directive when changing the file */
sc_is_utf8=(short)scan_utf8(inpf,name);
return TRUE;
}
@ -270,6 +268,11 @@ static void doinclude(int silent)
result=plungefile(name,(c!='>'),TRUE);
if (!result && !silent)
error(100,name); /* cannot read from ... (fatal error) */
#if !defined NO_DEFINE
if (result) {
inst_file_name(name, FALSE);
}
#endif
}
/* readline
@ -314,7 +317,6 @@ static void readline(unsigned char *line)
fline=i;
fcurrent=(short)POPSTK_I();
icomment=(short)POPSTK_I();
sc_is_utf8=(short)POPSTK_I();
iflevel=(short)POPSTK_I();
skiplevel=iflevel; /* this condition held before including the file */
assert(!SKIPPING); /* idem ditto */
@ -324,6 +326,9 @@ static void readline(unsigned char *line)
inpf=(FILE *)POPSTK_P();
insert_dbgfile(inpfname);
setfiledirect(inpfname);
#if !defined NO_DEFINE
inst_file_name(inpfname, TRUE);
#endif
assert(sc_status==statFIRST || strcmp(get_inputfile(fcurrent),inpfname)==0);
listline=-1; /* force a #line directive when changing the file */
} /* if */
@ -595,13 +600,6 @@ static int htoi(cell *val,const unsigned char *curptr)
return (int)(ptr-curptr);
}
#if defined __APPLE__
static double pow10(double d)
{
return pow(10, d);
}
#endif
/* ftoi
*
* Attempts to interpret a numeric symbol as a rational number, either as
@ -677,11 +675,7 @@ static int ftoi(cell *val,const unsigned char *curptr)
exp=(exp*10)+(*ptr-'0');
ptr++;
} /* while */
#if defined __GNUC__
fmult=pow10(exp*sign);
#else
fmult=pow(10,exp*sign);
#endif
fnum *= fmult;
dnum *= (unsigned long)(fmult+0.5);
} /* if */
@ -972,8 +966,14 @@ static int command(void)
if (strlen(pathname)>0) {
free(inpfname);
inpfname=duplicatestring(pathname);
if (inpfname==NULL)
if (inpfname==NULL) {
error(103); /* insufficient memory */
}
#if !defined NO_DEFINE
else {
inst_file_name(inpfname, TRUE);
}
#endif
} /* if */
} /* if */
check_empty(lptr);
@ -2381,21 +2381,12 @@ static cell litchar(const unsigned char **lptr,int flags)
cptr=*lptr;
if ((flags & RAWMODE)!=0 || *cptr!=sc_ctrlchar) { /* no escape character */
#if !defined NO_UTF8
if (sc_is_utf8 && (flags & UTF8MODE)!=0) {
c=get_utf8_char(cptr,&cptr);
assert(c>=0); /* file was already scanned for conformance to UTF-8 */
} else {
#endif
#if !defined NO_CODEPAGE
c=cp_translate(cptr,&cptr);
#else
c=*cptr;
cptr+=1;
#endif
#if !defined NO_UTF8
} /* if */
#endif
} else {
cptr+=1;
if (*cptr==sc_ctrlchar) {

67
compiler/libpc300/sc3.c Executable file → Normal file
View File

@ -1010,38 +1010,60 @@ static int hier13(value *lval)
{
int lvalue=plnge1(hier12,lval);
if (matchtoken('?')) {
int locheap=decl_heap; /* save current heap delta */
long heap1,heap2; /* max. heap delta either branch */
valuepair *heaplist_node;
int flab1=getlabel();
int flab2=getlabel();
value lval2 = {0};
int array1,array2;
int orig_heap=decl_heap;
int diff1=0,diff2=0;
if (lvalue) {
rvalue(lval);
} else if (lval->ident==iCONSTEXPR) {
ldconst(lval->constval,sPRI);
error(lval->constval ? 206 : 205); /* redundant test */
} /* if */
if (sc_status==statFIRST) {
/* We should push a new node right now otherwise we will pop it in the
* wrong order on the write stage.
*/
heaplist_node=push_heaplist(0,0); /* save the pointer to write the actual data later */
} else if (sc_status==statWRITE || sc_status==statSKIP) {
#if !defined NDEBUG
int result=
#endif
popfront_heaplist(&heap1,&heap2);
assert(result); /* pop off equally many items than were pushed */
} /* if */
jmp_eq0(flab1); /* go to second expression if primary register==0 */
PUSHSTK_I(sc_allowtags);
sc_allowtags=FALSE; /* do not allow tagnames here (colon is a special token) */
if (sc_status==statWRITE) {
modheap(heap1*sizeof(cell));
decl_heap+=heap1; /* equilibrate the heap (see comment below) */
} /* if */
if (hier13(lval))
rvalue(lval);
if (lval->ident==iCONSTEXPR) /* load constant here */
ldconst(lval->constval,sPRI);
sc_allowtags=(short)POPSTK_I(); /* restore */
heap1=decl_heap-locheap; /* save heap space used in "true" branch */
assert(heap1>=0);
decl_heap=locheap; /* restore heap delta */
jumplabel(flab2);
setlabel(flab1);
if (orig_heap!=decl_heap) {
diff1=abs(decl_heap-orig_heap);
decl_heap=orig_heap;
}
needtoken(':');
if (sc_status==statWRITE) {
modheap(heap2*sizeof(cell));
decl_heap+=heap2; /* equilibrate the heap (see comment below) */
} /* if */
if (hier13(&lval2))
rvalue(&lval2);
if (lval2.ident==iCONSTEXPR) /* load constant here */
ldconst(lval2.constval,sPRI);
heap2=decl_heap-locheap; /* save heap space used in "false" branch */
assert(heap2>=0);
array1= (lval->ident==iARRAY || lval->ident==iREFARRAY);
array2= (lval2.ident==iARRAY || lval2.ident==iREFARRAY);
if (array1 && !array2) {
@ -1055,19 +1077,26 @@ static int hier13(value *lval)
if (!matchtag(lval->tag,lval2.tag,FALSE))
error(213); /* tagname mismatch ('true' and 'false' expressions) */
setlabel(flab2);
if (sc_status==statFIRST) {
/* Calculate the max. heap space used by either branch and save values of
* max - heap1 and max - heap2. On the second pass, we use these values
* to equilibrate the heap space used by either branch. This is needed
* because we don't know (at compile time) which branch will be taken,
* but the heap cannot be restored inside each branch because the result
* on the heap may needed by the remaining expression.
*/
int max=(heap1>heap2) ? heap1 : heap2;
heaplist_node->first=max-heap1;
heaplist_node->second=max-heap2;
decl_heap=locheap+max; /* otherwise it will contain locheap+heap2 and the
* max. heap usage will be wrong for the upper
* expression */
} /* if */
assert(sc_status!=statWRITE || heap1==heap2);
if (lval->ident==iARRAY)
lval->ident=iREFARRAY; /* iARRAY becomes iREFARRAY */
else if (lval->ident!=iREFARRAY)
lval->ident=iEXPRESSION; /* iREFARRAY stays iREFARRAY, rest becomes iEXPRESSION */
if (orig_heap!=decl_heap) {
diff2=abs(decl_heap-orig_heap);
decl_heap=orig_heap;
}
if (diff1==diff2) {
decl_heap+=(diff1/2);
} else {
decl_heap+=(diff1+diff2);
}
return FALSE; /* conditional expression is no lvalue */
} else {
return lvalue;
@ -1160,6 +1189,7 @@ static int hier2(value *lval)
if (!check_userop(user_inc,lval->tag,0,1,lval,&lval->tag))
inc(lval); /* increase variable first */
rvalue(lval); /* and read the result into PRI */
lval->ident = iEXPRESSION;
sideeffect=TRUE;
return FALSE; /* result is no longer lvalue */
case tDEC: /* --lval */
@ -1171,6 +1201,7 @@ static int hier2(value *lval)
if (!check_userop(user_dec,lval->tag,0,1,lval,&lval->tag))
dec(lval); /* decrease variable first */
rvalue(lval); /* and read the result into PRI */
lval->ident = iEXPRESSION;
sideeffect=TRUE;
return FALSE; /* result is no longer lvalue */
case '~': /* ~ (one's complement) */
@ -1379,6 +1410,7 @@ static int hier2(value *lval)
inc(lval); /* increase variable afterwards */
if (saveresult)
popreg(sPRI); /* restore PRI (result of rvalue()) */
lval->ident = iEXPRESSION;
sideeffect=TRUE;
return FALSE; /* result is no longer lvalue */
case tDEC: /* lval-- */
@ -1397,6 +1429,7 @@ static int hier2(value *lval)
dec(lval); /* decrease variable afterwards */
if (saveresult)
popreg(sPRI); /* restore PRI (result of rvalue()) */
lval->ident = iEXPRESSION;
sideeffect=TRUE;
return FALSE;
case tCHAR: /* char (compute required # of cells */
@ -2054,7 +2087,8 @@ static int nesting=0;
error(35,argidx+1); /* argument type mismatch */
/* Verify that the dimensions match with those in arg[argidx].
* A literal array always has a single dimension.
* An iARRAYCELL parameter is also assumed to have a single dimension.
* An iARRAYCELL parameter is also assumed to have a single dimension,
* but its size may be >1 in case of an enumeration pseudo-array.
*/
if (lval.sym==NULL || lval.ident==iARRAYCELL) {
if (arg[argidx].numdim!=1) {
@ -2062,6 +2096,7 @@ static int nesting=0;
} else if (arg[argidx].dim[0]!=0) {
assert(arg[argidx].dim[0]>0);
if (lval.ident==iARRAYCELL) {
if (lval.constval==0 || arg[argidx].dim[0]!=lval.constval)
error(47); /* array sizes must match */
} else {
assert(lval.constval!=0); /* literal array must have a size */

View File

@ -309,120 +309,3 @@ SC_FUNC cell cp_translate(const unsigned char *string,const unsigned char **endp
}
#endif /* NO_CODEPAGE */
#if !defined NO_UTF8
SC_FUNC cell get_utf8_char(const unsigned char *string,const unsigned char **endptr)
{
int follow=0;
long lowmark=0;
unsigned char ch;
cell result=0;
if (endptr!=NULL)
*endptr=string;
for ( ;; ) {
ch=*string++;
if (follow>0 && (ch & 0xc0)==0x80) {
/* leader code is active, combine with earlier code */
result=(result << 6) | (ch & 0x3f);
if (--follow==0) {
/* encoding a character in more bytes than is strictly needed,
* is not really valid UTF-8; we are strict here to increase
* the chance of heuristic dectection of non-UTF-8 text
* (JAVA writes zero bytes as a 2-byte code UTF-8, which is invalid)
*/
if (result<lowmark)
return -1;
/* the code positions 0xd800--0xdfff and 0xfffe & 0xffff do not
* exist in UCS-4 (and hence, they do not exist in Unicode)
*/
if ((result>=0xd800 && result<=0xdfff) || result==0xfffe || result==0xffff)
return -1;
} /* if */
break;
} else if (follow==0 && (ch & 0x80)==0x80) {
/* UTF-8 leader code */
if ((ch & 0xe0)==0xc0) {
/* 110xxxxx 10xxxxxx */
follow=1;
lowmark=0x80L;
result=ch & 0x1f;
} else if ((ch & 0xf0)==0xe0) {
/* 1110xxxx 10xxxxxx 10xxxxxx (16 bits, BMP plane) */
follow=2;
lowmark=0x800L;
result=ch & 0x0f;
} else if ((ch & 0xf8)==0xf0) {
/* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
follow=3;
lowmark=0x10000L;
result=ch & 0x07;
} else if ((ch & 0xfc)==0xf8) {
/* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */
follow=4;
lowmark=0x200000L;
result=ch & 0x03;
} else if ((ch & 0xfe)==0xfc) {
/* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx (32 bits) */
follow=5;
lowmark=0x4000000L;
result=ch & 0x01;
} else {
/* this is invalid UTF-8 */
return -1;
} /* if */
} else if (follow==0 && (ch & 0x80)==0x00) {
/* 0xxxxxxx (US-ASCII) */
result=ch;
break;
} else {
/* this is invalid UTF-8 */
return -1;
} /* if */
} /* for */
if (endptr!=NULL)
*endptr=string;
return result;
}
#endif
SC_FUNC int scan_utf8(FILE *fp,const char *filename)
{
#if defined NO_UTF8
return 0;
#else
static void *resetpos=NULL;
int utf8=TRUE;
int firstchar=TRUE,bom_found=FALSE;
const unsigned char *ptr;
resetpos=pc_getpossrc(fp);
while (utf8 && pc_readsrc(fp,pline,sLINEMAX)!=NULL) {
ptr=pline;
if (firstchar) {
/* check whether the very first character on the very first line
* starts with a BYTE order mark
*/
cell c=get_utf8_char(ptr,&ptr);
bom_found= (c==0xfeff);
utf8= (c>=0);
firstchar=FALSE;
} /* if */
while (utf8 && *ptr!='\0')
utf8= (get_utf8_char(ptr,&ptr)>=0);
} /* while */
pc_resetsrc(fp,resetpos);
if (bom_found) {
unsigned char bom[3];
if (!utf8)
error(77,filename); /* malformed UTF-8 encoding */
pc_readsrc(fp,bom,3);
assert(bom[0]==0xef && bom[1]==0xbb && bom[2]==0xbf);
} /* if */
return utf8;
#endif /* NO_UTF8 */
}

View File

@ -443,6 +443,52 @@ SC_FUNC void delete_autolisttable(void)
}
/* ----- value pair list ----------------------------------------- */
static valuepair heaplist = {NULL, 0, 0};
SC_FUNC valuepair *push_heaplist(long first, long second)
{
valuepair *cur, *last;
if ((cur=malloc(sizeof(valuepair)))==NULL)
error(103); /* insufficient memory (fatal error) */
cur->first=first;
cur->second=second;
cur->next=NULL;
for (last=&heaplist; last->next!=NULL; last=last->next)
/* nothing */;
last->next=cur;
return cur;
}
SC_FUNC int popfront_heaplist(long *first, long *second)
{
valuepair *front=heaplist.next;
if (front==NULL)
return 0;
/* copy fields */
*first=front->first;
*second=front->second;
/* unlink and free */
heaplist.next=front->next;
free(front);
return 1;
}
SC_FUNC void delete_heaplisttable(void)
{
valuepair *cur;
while (heaplist.next!=NULL) {
cur=heaplist.next;
heaplist.next=cur->next;
free(cur);
} /* while */
}
/* ----- debug information --------------------------------------- */
static stringlist dbgstrings = {NULL, NULL};

View File

@ -84,7 +84,6 @@ SC_VDEFINE int sc_status; /* read/write status */
SC_VDEFINE int sc_rationaltag=0; /* tag for rational numbers */
SC_VDEFINE int rational_digits=0; /* number of fractional digits */
SC_VDEFINE int sc_allowproccall=0; /* allow/detect tagnames in lex() */
SC_VDEFINE short sc_is_utf8=FALSE; /* is this source file in UTF-8 encoding */
SC_VDEFINE char *pc_deprecate = NULL;/* if non-null, mark next declaration as deprecated */
SC_VDEFINE int sc_showincludes=0; /* show include files */
SC_VDEFINE int sc_warnings_are_errors=0;

View File

@ -156,6 +156,11 @@ amx_language_display_msg 1
// Default value: 1
amx_help_display_msg 1
// Time to wait (in seconds) before displaying a message about amx_help to a client once joined the server
//
// Default value: 15
amx_help_display_msg_time 15
// Amount of commands per amx_help page
//
// Default value: 10

View File

@ -1,5 +1,5 @@
; Menu configuration file
; Default File location: $moddir/addons/amxmodx/configs/clcmds.ini
; File location: $moddir/addons/amxmodx/configs/clcmds.ini
; To use with Players Menu plugin
; NOTE: By default in all settings the access level is set to "u".

View File

@ -40,3 +40,8 @@ max_binlog_size 20
; 2 - float comparisons
; 4 - float rounding
optimizer 7
; Admin command flag manager
; 0 - enabled
; 1 - disabled
disableflagman 0

View File

@ -156,6 +156,11 @@ amx_language_display_msg 1
// Default value: 1
amx_help_display_msg 1
// Time to wait (in seconds) before displaying a message about amx_help to a client once joined the server
//
// Default value: 15
amx_help_display_msg_time 15
// Amount of commands per amx_help page
//
// Default value: 10
@ -210,3 +215,9 @@ amx_statsx_duration 12.0
// Default value: -2.0
amx_statsx_freeze -2.0
// Sets whether Restrict Weapons plugin should use a configuration file per map or or not.
// If enabled, the file format is: weaprest_mapname.ini (e.g. weaprest_de_dust.ini).
// -
// Default value: 0
amx_restrmapsettings 0

View File

@ -18,6 +18,9 @@ csstats_score addons/amxmodx/data/csstats.amxx
; 3 - HL Logs
amxx_logging 1
; MySQL default timeout
mysql_timeout 60
; Binary logging level
; add these up to get what you want
; these only work with bin logging binaries
@ -40,3 +43,8 @@ max_binlog_size 20
; 2 - float comparisons
; 4 - float rounding
optimizer 7
; Admin command flag manager
; 0 - enabled
; 1 - disabled
disableflagman 0

View File

@ -7,6 +7,9 @@ amxx_plugins addons/amxmodx/configs/plugins.ini
amxx_pluginsdir addons/amxmodx/plugins
amxx_modulesdir addons/amxmodx/modules
amxx_vault addons/amxmodx/data/vault.ini
; It is important that "dodstats" comes before "dodstats_score"
dodstats addons/amxmodx/data/dodstats.dat
dodstats_score addons/amxmodx/data/dodstats.amxx
; Logging mode
; 0 - no logging
@ -15,9 +18,8 @@ amxx_vault addons/amxmodx/data/vault.ini
; 3 - HL Logs
amxx_logging 1
; It is important that "dodstats" comes before "dodstats_score"
dodstats addons/amxmodx/data/dodstats.dat
dodstats_score addons/amxmodx/data/dodstats.amxx
; MySQL default timeout
mysql_timeout 60
; Binary logging level
; add these up to get what you want
@ -41,3 +43,8 @@ max_binlog_size 20
; 2 - float comparisons
; 4 - float rounding
optimizer 7
; Admin command flag manager
; 0 - enabled
; 1 - disabled
disableflagman 0

File diff suppressed because it is too large Load Diff

View File

@ -156,6 +156,11 @@ amx_language_display_msg 1
// Default value: 1
amx_help_display_msg 1
// Time to wait (in seconds) before displaying a message about amx_help to a client once joined the server
//
// Default value: 15
amx_help_display_msg_time 15
// Amount of commands per amx_help page
//
// Default value: 10

View File

@ -4,7 +4,7 @@
; Line starting with ; is a comment
; Access flags:
; a - immunity (can't be kicked/baned/slayed/slaped and affected by other commmands)
; a - immunity (can't be kicked/banned/slayed/slapped and affected by other commmands)
; b - reservation (can join on reserved slots)
; c - amx_kick command
; d - amx_ban and amx_unban commands (permanent and temporary bans)
@ -34,6 +34,9 @@
; c - this is steamid/wonid
; d - this is ip
; e - password is not checked (only name/ip/steamid needed)
; k - name or tag is case sensitive. eg: if you set it so the name "Ham"
; is protected and case sensitive (flags "k" only), then anybody
; can use the names "haM", "HAM", "ham", etc, but not "Ham"
; Password:
; Add to your autoexec.cfg: setinfo _pw "<password>"

View File

@ -18,6 +18,9 @@ tfcstats_score addons/amxmodx/data/tfcstats.amxx
; 3 - HL Logs
amxx_logging 1
; MySQL default timeout
mysql_timeout 60
; Binary logging level
; add these up to get what you want
; these only work with bin logging binaries
@ -40,3 +43,8 @@ max_binlog_size 20
; 2 - float comparisons
; 4 - float rounding
optimizer 7
; Admin command flag manager
; 0 - enabled
; 1 - disabled
disableflagman 0

View File

@ -18,6 +18,9 @@ tsstats_score addons/amxmodx/data/tsstats.amxx
; 3 - HL Logs
amxx_logging 1
; MySQL default timeout
mysql_timeout 60
; Binary logging level
; add these up to get what you want
; these only work with bin logging binaries
@ -40,3 +43,8 @@ max_binlog_size 20
; 2 - float comparisons
; 4 - float rounding
optimizer 7
; Admin command flag manager
; 0 - enabled
; 1 - disabled
disableflagman 0

View File

@ -30,4 +30,6 @@ run.options.add_option('--mysql', type='string', dest='mysql_path', default='',
help='Path to MySQL')
run.options.add_option('--disable-auto-versioning', action='store_true', dest='disable_auto_versioning',
default=False, help='Disable the auto versioning script')
run.options.add_option('--nasm', type='string', dest='nasm_path',
default='nasm', help='Path to NASM')
run.Configure()

View File

@ -7369,6 +7369,7 @@ object frmMain: TfrmMain
'list_store_string'
'log_amx'
'log_message'
'elog_message'
'log_to_file'
'make_deathmsg'
'make_string'

View File

@ -389,7 +389,7 @@ server_changelevel plugin_cfg plugin_end plugin_log plugin_precache client_infoc
set_localinfo get_localinfo show_motd client_print engclient_print console_print console_cmd register_event register_logevent set_hudmessage show_hudmessage show_menu read_data read_datanum read_logdata read_logargc read_logargv\
parse_loguser server_print is_map_valid is_user_bot is_user_hltv is_user_connected is_user_connecting is_user_alive is_dedicated_server is_linux_server is_jit_enabled get_amxx_verstring get_user_attacker get_user_aiming get_user_frags get_user_armor get_user_deaths\
get_user_health get_user_index get_user_ip user_has_weapon get_user_weapon get_user_ammo num_to_word get_user_team get_user_time get_user_ping get_user_origin get_user_weapons get_weaponname get_user_name get_user_authid get_user_userid user_slap\
user_kill log_amx log_message log_to_file get_playersnum get_players read_argv read_args read_argc read_flags get_flags find_player remove_quotes client_cmd engclient_cmd server_cmd set_cvar_string\
user_kill log_amx log_message elog_message log_to_file get_playersnum get_players read_argv read_args read_argc read_flags get_flags find_player remove_quotes client_cmd engclient_cmd server_cmd set_cvar_string\
cvar_exists remove_cvar_flags set_cvar_flags get_cvar_flags set_cvar_float get_cvar_float get_cvar_num set_cvar_num get_cvar_string get_mapname get_timeleft get_gametime get_maxplayers get_modname get_time format_time get_systime\
parse_time set_task remove_task change_task task_exists set_user_flags get_user_flags remove_user_flags register_clcmd register_concmd register_srvcmd get_clcmd get_clcmdsnum get_srvcmd get_srvcmdsnum get_concmd get_concmd_plid\
get_concmdsnum get_plugins_cvarsnum get_plugins_cvar register_menuid register_menucmd get_user_menu server_exec emit_sound register_cvar random_float random_num get_user_msgid get_user_msgname xvar_exists get_xvar_id get_xvar_num get_xvar_float\

View File

@ -743,6 +743,25 @@
"game" "czero"
}
"gamerules.games/cstrike/offsets-cgamerules.txt"
{
"game" "cstrike"
"game" "czero"
}
"gamerules.games/cstrike/offsets-chalflifemultiplay.txt"
{
"game" "cstrike"
"game" "czero"
}
"gamerules.games/cstrike/offsets-chalflifetraining.txt"
{
"game" "cstrike"
"game" "czero"
}
//
// Day Of Defeat
@ -1533,6 +1552,16 @@
"game" "dod"
}
"gamerules.games/dod/offsets-cdodteamplay.txt"
{
"game" "dod"
}
"gamerules.games/dod/offsets-cspdodrules.txt"
{
"game" "dod"
}
//
// Team Fortress Classic
@ -2158,6 +2187,20 @@
"game" "tfc"
}
"gamerules.games/tfc/offsets-chalflifemultiplay.txt"
{
"game" "tfc"
}
"gamerules.games/tfc/offsets-chalflifeteamplay.txt"
{
"game" "tfc"
}
"gamerules.games/tfc/offsets-cteamfortress.txt"
{
"game" "tfc"
}
//
// Half-Life: Opposing Force
@ -3338,6 +3381,25 @@
"game" "gearbox"
}
"gamerules.games/gearbox/offsets-chalflifemultiplay.txt"
{
"game" "gearbox"
}
"gamerules.games/gearbox/offsets-chalflifectfplay.txt"
{
"game" "gearbox"
}
"gamerules.games/gearbox/offsets-chalflifecoopplay.txt"
{
"game" "gearbox"
}
"gamerules.games/gearbox/offsets-chalflifeteamplay.txt"
{
"game" "gearbox"
}
//
// Half-Life: Deathmatch
@ -4032,4 +4094,78 @@
{
"game" "valve"
}
"gamerules.games/valve/offsets-chalflifemultiplay.txt"
{
"game" "valve"
}
"gamerules.games/valve/offsets-chalflifeteamplay.txt"
{
"game" "valve"
}
//
// Virtual Functions
//
"virtual.games/ag/offsets-common.txt"
{
"game" "ag"
}
"virtual.games/cstrike/offsets-common.txt"
{
"game" "cstrike"
"game" "czero"
}
"virtual.games/dod/offsets-common.txt"
{
"game" "dod"
}
"virtual.games/esf/offsets-common.txt"
{
"game" "esf"
}
"virtual.games/esf_openbeta/offsets-common.txt"
{
"game" "esf_openbeta"
}
"virtual.games/gearbox/offsets-common.txt"
{
"game" "gearbox"
}
"virtual.games/ns/offsets-common.txt"
{
"game" "ns"
"game" "nsp"
}
"virtual.games/svencoop/offsets-common.txt"
{
"game" "svencoop"
}
"virtual.games/tfc/offsets-common.txt"
{
"game" "tfc"
}
"virtual.games/ts/offsets-common.txt"
{
"game" "ts"
}
"virtual.games/valve/offsets-common.txt"
{
"game" "valve"
"game" "dmc"
}
}

View File

@ -0,0 +1,938 @@
/**
* Do not edit this file. Any changes will be overwritten by the gamedata
* updater or by upgrading your AMX Mod X install.
*
* To override data in this file, create a subdirectory named "custom" and
* place your own gamedata file(s) inside of it. Such files will be parsed
* after AMXX's own.
*
* For more information, see http://wiki.alliedmods.net/Gamedata_Updating_(AMX_Mod_X)
*/
"Games"
{
"#default"
{
"Offsets"
{
"pev"
{
"windows" "4"
"linux" "0"
}
"base"
{
"windows" "0x0"
"linux" "0x60"
}
"spawn"
{
"windows" "0"
"linux" "2"
}
"precache"
{
"windows" "1"
"linux" "3"
}
"keyvalue"
{
"windows" "2"
"linux" "4"
}
"objectcaps"
{
"windows" "5"
"linux" "7"
}
"activate"
{
"windows" "6"
"linux" "8"
}
"setobjectcollisionbox"
{
"windows" "7"
"linux" "9"
}
"classify"
{
"windows" "8"
"linux" "10"
}
"deathnotice"
{
"windows" "9"
"linux" "11"
}
"traceattack"
{
"windows" "10"
"linux" "12"
}
"takedamage"
{
"windows" "11"
"linux" "13"
}
"takehealth"
{
"windows" "12"
"linux" "14"
}
"killed"
{
"windows" "13"
"linux" "15"
}
"bloodcolor"
{
"windows" "14"
"linux" "16"
}
"tracebleed"
{
"windows" "15"
"linux" "17"
}
"istriggered"
{
"windows" "16"
"linux" "18"
}
"mymonsterpointer"
{
"windows" "17"
"linux" "19"
}
"mysquadmonsterpointer"
{
"windows" "18"
"linux" "20"
}
"gettogglestate"
{
"windows" "19"
"linux" "21"
}
"addpoints"
{
"windows" "20"
"linux" "22"
}
"addpointstoteam"
{
"windows" "21"
"linux" "23"
}
"addplayeritem"
{
"windows" "22"
"linux" "24"
}
"removeplayeritem"
{
"windows" "23"
"linux" "25"
}
"giveammo"
{
"windows" "24"
"linux" "26"
}
"getdelay"
{
"windows" "25"
"linux" "27"
}
"ismoving"
{
"windows" "26"
"linux" "28"
}
"overridereset"
{
"windows" "27"
"linux" "29"
}
"damagedecal"
{
"windows" "28"
"linux" "30"
}
"settogglestate"
{
"windows" "29"
"linux" "31"
}
"startsneaking"
{
"windows" "30"
"linux" "32"
}
"stopsneaking"
{
"windows" "31"
"linux" "33"
}
"oncontrols"
{
"windows" "32"
"linux" "34"
}
"issneaking"
{
"windows" "33"
"linux" "35"
}
"isalive"
{
"windows" "34"
"linux" "36"
}
"isbspmodel"
{
"windows" "35"
"linux" "37"
}
"reflectgauss"
{
"windows" "36"
"linux" "38"
}
"hastarget"
{
"windows" "37"
"linux" "39"
}
"isinworld"
{
"windows" "38"
"linux" "40"
}
"isplayer"
{
"windows" "39"
"linux" "41"
}
"isnetclient"
{
"windows" "40"
"linux" "42"
}
"teamid"
{
"windows" "41"
"linux" "43"
}
"getnexttarget"
{
"windows" "42"
"linux" "44"
}
"think"
{
"windows" "43"
"linux" "45"
}
"touch"
{
"windows" "44"
"linux" "46"
}
"use"
{
"windows" "45"
"linux" "47"
}
"blocked"
{
"windows" "46"
"linux" "48"
}
"respawn"
{
"windows" "48"
"linux" "50"
}
"updateowner"
{
"windows" "49"
"linux" "51"
}
"fbecomeprone"
{
"windows" "50"
"linux" "52"
}
"center"
{
"windows" "51"
"linux" "53"
}
"eyeposition"
{
"windows" "52"
"linux" "54"
}
"earposition"
{
"windows" "53"
"linux" "55"
}
"bodytarget"
{
"windows" "54"
"linux" "56"
}
"illumination"
{
"windows" "55"
"linux" "57"
}
"fvisible"
{
"windows" "56"
"linux" "58"
}
"fvecvisible"
{
"windows" "57"
"linux" "59"
}
"look"
{
"windows" "60"
"linux" "62"
}
"changeyaw"
{
"windows" "63"
"linux" "65"
}
"irelationship"
{
"windows" "65"
"linux" "67"
}
"monsterinitdead"
{
"windows" "67"
"linux" "69"
}
"becomedead"
{
"windows" "68"
"linux" "70"
}
"bestvisibleenemy"
{
"windows" "70"
"linux" "72"
}
"finviewcone"
{
"windows" "71"
"linux" "73"
}
"fvecinviewcone"
{
"windows" "72"
"linux" "74"
}
"runai"
{
"windows" "61"
"linux" "63"
}
"monsterthink"
{
"windows" "64"
"linux" "66"
}
"monsterinit"
{
"windows" "66"
"linux" "68"
}
"checklocalmove"
{
"windows" "73"
"linux" "75"
}
"move"
{
"windows" "74"
"linux" "76"
}
"moveexecute"
{
"windows" "75"
"linux" "77"
}
"shouldadvanceroute"
{
"windows" "76"
"linux" "78"
}
"getstoppedactivity"
{
"windows" "77"
"linux" "79"
}
"stop"
{
"windows" "78"
"linux" "80"
}
"checkrangeattack1"
{
"windows" "79"
"linux" "81"
}
"checkrangeattack2"
{
"windows" "80"
"linux" "82"
}
"checkmeleeattack1"
{
"windows" "81"
"linux" "83"
}
"checkmeleeattack2"
{
"windows" "82"
"linux" "84"
}
"schedulechange"
{
"windows" "88"
"linux" "90"
}
"canplaysequence"
{
"windows" "89"
"linux" "91"
}
"canplaysentence"
{
"windows" "90"
"linux" "92"
}
"playsentence"
{
"windows" "91"
"linux" "93"
}
"playscriptedsentence"
{
"windows" "92"
"linux" "94"
}
"sentencestop"
{
"windows" "93"
"linux" "95"
}
"getidealstate"
{
"windows" "94"
"linux" "96"
}
"setactivity"
{
"windows" "95"
"linux" "97"
}
"reportaistate"
{
"windows" "96"
"linux" "98"
}
"checkenemy"
{
"windows" "97"
"linux" "99"
}
"ftriangulate"
{
"windows" "98"
"linux" "100"
}
"setyawspeed"
{
"windows" "99"
"linux" "101"
}
"buildnearestroute"
{
"windows" "100"
"linux" "102"
}
"findcover"
{
"windows" "101"
"linux" "103"
}
"coverradius"
{
"windows" "103"
"linux" "105"
}
"fcancheckattacks"
{
"windows" "104"
"linux" "106"
}
"checkammo"
{
"windows" "105"
"linux" "107"
}
"ignoreconditions"
{
"windows" "106"
"linux" "108"
}
"fvalidatehinttype"
{
"windows" "107"
"linux" "109"
}
"fcanactiveidle"
{
"windows" "108"
"linux" "110"
}
"isoundmask"
{
"windows" "109"
"linux" "111"
}
"hearingsensitivity"
{
"windows" "112"
"linux" "114"
}
"barnaclevictimbitten"
{
"windows" "113"
"linux" "115"
}
"barnaclevictimreleased"
{
"windows" "114"
"linux" "116"
}
"preschedulethink"
{
"windows" "115"
"linux" "117"
}
"getdeathactivity"
{
"windows" "116"
"linux" "118"
}
"gibmonster"
{
"windows" "117"
"linux" "119"
}
"hashumangibs"
{
"windows" "118"
"linux" "120"
}
"hasaliengibs"
{
"windows" "119"
"linux" "121"
}
"fademonster"
{
"windows" "120"
"linux" "122"
}
"deathsound"
{
"windows" "122"
"linux" "124"
}
"alertsound"
{
"windows" "123"
"linux" "125"
}
"idlesound"
{
"windows" "124"
"linux" "126"
}
"painsound"
{
"windows" "125"
"linux" "127"
}
"stopfollowing"
{
"windows" "126"
"linux" "128"
}
"player_jump"
{
"windows" "127"
"linux" "129"
}
"player_duck"
{
"windows" "128"
"linux" "130"
}
"player_prethink"
{
"windows" "129"
"linux" "131"
}
"player_postthink"
{
"windows" "130"
"linux" "132"
}
"player_getgunposition"
{
"windows" "121"
"linux" "123"
}
"player_shouldfadeondeath"
{
"windows" "62"
"linux" "64"
}
"player_impulsecommands"
{
"windows" "132"
"linux" "134"
}
"player_updateclientdata"
{
"windows" "131"
"linux" "133"
}
"item_addtoplayer"
{
"windows" "59"
"linux" "61"
}
"item_addduplicate"
{
"windows" "60"
"linux" "62"
}
"item_getiteminfo"
{
"windows" "61"
"linux" "63"
}
"item_candeploy"
{
"windows" "62"
"linux" "64"
}
"item_deploy"
{
"windows" "63"
"linux" "65"
}
"item_canholster"
{
"windows" "64"
"linux" "66"
}
"item_holster"
{
"windows" "65"
"linux" "67"
}
"item_updateiteminfo"
{
"windows" "66"
"linux" "68"
}
"item_preframe"
{
"windows" "67"
"linux" "69"
}
"item_postframe"
{
"windows" "68"
"linux" "70"
}
"item_drop"
{
"windows" "69"
"linux" "71"
}
"item_kill"
{
"windows" "70"
"linux" "72"
}
"item_attachtoplayer"
{
"windows" "71"
"linux" "73"
}
"item_primaryammoindex"
{
"windows" "72"
"linux" "74"
}
"item_secondaryammoindex"
{
"windows" "73"
"linux" "75"
}
"item_updateclientdata"
{
"windows" "74"
"linux" "76"
}
"item_getweaponptr"
{
"windows" "75"
"linux" "77"
}
"item_itemslot"
{
"windows" "76"
"linux" "78"
}
"weapon_extractammo"
{
"windows" "77"
"linux" "79"
}
"weapon_extractclipammo"
{
"windows" "78"
"linux" "80"
}
"weapon_addweapon"
{
"windows" "79"
"linux" "81"
}
"weapon_playemptysound"
{
"windows" "80"
"linux" "82"
}
"weapon_resetemptysound"
{
"windows" "81"
"linux" "83"
}
"weapon_sendweaponanim"
{
"windows" "82"
"linux" "84"
}
"weapon_isusable"
{
"windows" "83"
"linux" "85"
}
"weapon_primaryattack"
{
"windows" "84"
"linux" "86"
}
"weapon_secondaryattack"
{
"windows" "85"
"linux" "87"
}
"weapon_reload"
{
"windows" "86"
"linux" "88"
}
"weapon_weaponidle"
{
"windows" "87"
"linux" "89"
}
"weapon_retireweapon"
{
"windows" "88"
"linux" "90"
}
"weapon_shouldweaponidle"
{
"windows" "89"
"linux" "91"
}
"weapon_usedecrement"
{
"windows" "90"
"linux" "92"
}
}
}
}

View File

@ -0,0 +1,874 @@
/**
* Do not edit this file. Any changes will be overwritten by the gamedata
* updater or by upgrading your AMX Mod X install.
*
* To override data in this file, create a subdirectory named "custom" and
* place your own gamedata file(s) inside of it. Such files will be parsed
* after AMXX's own.
*
* For more information, see http://wiki.alliedmods.net/Gamedata_Updating_(AMX_Mod_X)
*/
"Games"
{
"#default"
{
"Offsets"
{
"pev"
{
"windows" "4"
"linux" "4"
"mac" "4"
}
"base"
{
"windows" "0x0"
"linux" "0x0"
"mac" "0x0"
}
"spawn"
{
"windows" "0"
"linux" "0"
"mac" "0"
}
"precache"
{
"windows" "1"
"linux" "1"
"mac" "1"
}
"keyvalue"
{
"windows" "3"
"linux" "3"
"mac" "3"
}
"objectcaps"
{
"windows" "6"
"linux" "6"
"mac" "6"
}
"activate"
{
"windows" "7"
"linux" "7"
"mac" "7"
}
"setobjectcollisionbox"
{
"windows" "8"
"linux" "8"
"mac" "8"
}
"classify"
{
"windows" "9"
"linux" "9"
"mac" "9"
}
"deathnotice"
{
"windows" "10"
"linux" "10"
"mac" "10"
}
"traceattack"
{
"windows" "11"
"linux" "11"
"mac" "11"
}
"takedamage"
{
"windows" "12"
"linux" "12"
"mac" "12"
}
"takehealth"
{
"windows" "13"
"linux" "13"
"mac" "13"
}
"killed"
{
"windows" "14"
"linux" "14"
"mac" "14"
}
"bloodcolor"
{
"windows" "15"
"linux" "15"
"mac" "15"
}
"tracebleed"
{
"windows" "16"
"linux" "16"
"mac" "16"
}
"istriggered"
{
"windows" "17"
"linux" "17"
"mac" "17"
}
"mymonsterpointer"
{
"windows" "18"
"linux" "18"
"mac" "18"
}
"mysquadmonsterpointer"
{
"windows" "19"
"linux" "19"
"mac" "19"
}
"gettogglestate"
{
"windows" "20"
"linux" "20"
"mac" "20"
}
"addpoints"
{
"windows" "21"
"linux" "21"
"mac" "21"
}
"addpointstoteam"
{
"windows" "22"
"linux" "22"
"mac" "22"
}
"addplayeritem"
{
"windows" "23"
"linux" "23"
"mac" "23"
}
"removeplayeritem"
{
"windows" "24"
"linux" "24"
"mac" "24"
}
"giveammo"
{
"windows" "25"
"linux" "25"
"mac" "25"
}
"getdelay"
{
"windows" "26"
"linux" "26"
"mac" "26"
}
"ismoving"
{
"windows" "27"
"linux" "27"
"mac" "27"
}
"overridereset"
{
"windows" "28"
"linux" "28"
"mac" "28"
}
"damagedecal"
{
"windows" "29"
"linux" "29"
"mac" "29"
}
"settogglestate"
{
"windows" "30"
"linux" "30"
"mac" "30"
}
"startsneaking"
{
"windows" "31"
"linux" "31"
"mac" "31"
}
"stopsneaking"
{
"windows" "32"
"linux" "32"
"mac" "32"
}
"oncontrols"
{
"windows" "33"
"linux" "33"
"mac" "33"
}
"issneaking"
{
"windows" "34"
"linux" "34"
"mac" "34"
}
"isalive"
{
"windows" "35"
"linux" "35"
"mac" "35"
}
"isbspmodel"
{
"windows" "36"
"linux" "36"
"mac" "36"
}
"reflectgauss"
{
"windows" "37"
"linux" "37"
"mac" "37"
}
"hastarget"
{
"windows" "38"
"linux" "38"
"mac" "38"
}
"isinworld"
{
"windows" "39"
"linux" "39"
"mac" "39"
}
"isplayer"
{
"windows" "40"
"linux" "40"
"mac" "40"
}
"isnetclient"
{
"windows" "41"
"linux" "41"
"mac" "41"
}
"teamid"
{
"windows" "42"
"linux" "42"
"mac" "42"
}
"getnexttarget"
{
"windows" "43"
"linux" "43"
"mac" "43"
}
"think"
{
"windows" "44"
"linux" "44"
"mac" "44"
}
"touch"
{
"windows" "45"
"linux" "45"
"mac" "45"
}
"use"
{
"windows" "46"
"linux" "46"
"mac" "46"
}
"blocked"
{
"windows" "47"
"linux" "47"
"mac" "47"
}
"respawn"
{
"windows" "48"
"linux" "48"
"mac" "48"
}
"updateowner"
{
"windows" "49"
"linux" "49"
"mac" "49"
}
"fbecomeprone"
{
"windows" "50"
"linux" "50"
"mac" "50"
}
"center"
{
"windows" "51"
"linux" "51"
"mac" "51"
}
"eyeposition"
{
"windows" "52"
"linux" "52"
"mac" "52"
}
"earposition"
{
"windows" "53"
"linux" "53"
"mac" "53"
}
"bodytarget"
{
"windows" "54"
"linux" "54"
"mac" "54"
}
"illumination"
{
"windows" "55"
"linux" "55"
"mac" "55"
}
"fvisible"
{
"windows" "56"
"linux" "56"
"mac" "56"
}
"fvecvisible"
{
"windows" "57"
"linux" "57"
"mac" "57"
}
"changeyaw"
{
"windows" "59"
"linux" "59"
"mac" "59"
}
"hashumangibs"
{
"windows" "60"
"linux" "60"
"mac" "60"
}
"hasaliengibs"
{
"windows" "61"
"linux" "61"
"mac" "61"
}
"fademonster"
{
"windows" "62"
"linux" "62"
"mac" "62"
}
"gibmonster"
{
"windows" "63"
"linux" "63"
"mac" "63"
}
"getdeathactivity"
{
"windows" "64"
"linux" "64"
"mac" "64"
}
"becomedead"
{
"windows" "65"
"linux" "65"
"mac" "65"
}
"irelationship"
{
"windows" "67"
"linux" "67"
"mac" "67"
}
"painsound"
{
"windows" "68"
"linux" "68"
"mac" "68"
}
"reportaistate"
{
"windows" "70"
"linux" "70"
"mac" "70"
}
"monsterinitdead"
{
"windows" "71"
"linux" "71"
"mac" "71"
}
"look"
{
"windows" "72"
"linux" "72"
"mac" "72"
}
"bestvisibleenemy"
{
"windows" "73"
"linux" "73"
"mac" "73"
}
"finviewcone"
{
"windows" "75"
"linux" "74"
"mac" "74"
}
"fvecinviewcone"
{
"windows" "74"
"linux" "75"
"mac" "75"
}
"player_jump"
{
"windows" "76"
"linux" "76"
"mac" "76"
}
"player_duck"
{
"windows" "77"
"linux" "77"
"mac" "77"
}
"player_prethink"
{
"windows" "78"
"linux" "78"
"mac" "78"
}
"player_postthink"
{
"windows" "79"
"linux" "79"
"mac" "79"
}
"player_getgunposition"
{
"windows" "80"
"linux" "80"
"mac" "80"
}
"player_shouldfadeondeath"
{
"windows" "66"
"linux" "66"
"mac" "66"
}
"player_impulsecommands"
{
"windows" "83"
"linux" "83"
"mac" "83"
}
"player_updateclientdata"
{
"windows" "82"
"linux" "82"
"mac" "82"
}
"item_addtoplayer"
{
"windows" "59"
"linux" "59"
"mac" "59"
}
"item_addduplicate"
{
"windows" "60"
"linux" "60"
"mac" "60"
}
"item_getiteminfo"
{
"windows" "61"
"linux" "61"
"mac" "61"
}
"item_candeploy"
{
"windows" "62"
"linux" "62"
"mac" "62"
}
"item_deploy"
{
"windows" "64"
"linux" "64"
"mac" "64"
}
"item_canholster"
{
"windows" "66"
"linux" "66"
"mac" "66"
}
"item_holster"
{
"windows" "67"
"linux" "67"
"mac" "67"
}
"item_updateiteminfo"
{
"windows" "68"
"linux" "68"
"mac" "68"
}
"item_preframe"
{
"windows" "69"
"linux" "69"
"mac" "69"
}
"item_postframe"
{
"windows" "70"
"linux" "70"
"mac" "70"
}
"item_drop"
{
"windows" "71"
"linux" "71"
"mac" "71"
}
"item_kill"
{
"windows" "72"
"linux" "72"
"mac" "72"
}
"item_attachtoplayer"
{
"windows" "73"
"linux" "73"
"mac" "73"
}
"item_primaryammoindex"
{
"windows" "74"
"linux" "74"
"mac" "74"
}
"item_secondaryammoindex"
{
"windows" "75"
"linux" "75"
"mac" "75"
}
"item_updateclientdata"
{
"windows" "76"
"linux" "76"
"mac" "76"
}
"item_getweaponptr"
{
"windows" "77"
"linux" "77"
"mac" "77"
}
"item_itemslot"
{
"windows" "79"
"linux" "79"
"mac" "79"
}
"weapon_extractammo"
{
"windows" "80"
"linux" "80"
"mac" "80"
}
"weapon_extractclipammo"
{
"windows" "81"
"linux" "81"
"mac" "81"
}
"weapon_addweapon"
{
"windows" "82"
"linux" "82"
"mac" "82"
}
"weapon_playemptysound"
{
"windows" "83"
"linux" "83"
"mac" "83"
}
"weapon_resetemptysound"
{
"windows" "84"
"linux" "84"
"mac" "84"
}
"weapon_isusable"
{
"windows" "86"
"linux" "86"
"mac" "86"
}
"weapon_primaryattack"
{
"windows" "87"
"linux" "87"
"mac" "87"
}
"weapon_secondaryattack"
{
"windows" "88"
"linux" "88"
"mac" "88"
}
"weapon_reload"
{
"windows" "89"
"linux" "89"
"mac" "89"
}
"weapon_weaponidle"
{
"windows" "90"
"linux" "90"
"mac" "90"
}
"weapon_retireweapon"
{
"windows" "91"
"linux" "91"
"mac" "91"
}
"weapon_shouldweaponidle"
{
"windows" "92"
"linux" "92"
"mac" "92"
}
"weapon_usedecrement"
{
"windows" "93"
"linux" "93"
"mac" "93"
}
"cstrike_restart"
{
"windows" "2"
"linux" "2"
"mac" "2"
}
"cstrike_roundrespawn"
{
"windows" "84"
"linux" "84"
"mac" "84"
}
"cstrike_item_candrop"
{
"windows" "63"
"linux" "63"
"mac" "63"
}
"cstrike_item_isweapon"
{
"windows" "65"
"linux" "65"
"mac" "65"
}
"cstrike_item_getmaxspeed"
{
"windows" "78"
"linux" "78"
"mac" "78"
}
"cstrike_weapon_sendweaponanim"
{
"windows" "85"
"linux" "85"
"mac" "85"
}
"cstrike_player_resetmaxspeed"
{
"windows" "69"
"linux" "69"
"mac" "69"
}
"cstrike_player_isbot"
{
"windows" "81"
"linux" "81"
"mac" "81"
}
"cstrike_player_getautoaimvector"
{
"windows" "85"
"linux" "85"
"mac" "85"
}
"cstrike_player_blind"
{
"windows" "86"
"linux" "86"
"mac" "86"
}
"cstrike_player_ontouchingweapon"
{
"windows" "87"
"linux" "87"
"mac" "87"
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,902 @@
/**
* Do not edit this file. Any changes will be overwritten by the gamedata
* updater or by upgrading your AMX Mod X install.
*
* To override data in this file, create a subdirectory named "custom" and
* place your own gamedata file(s) inside of it. Such files will be parsed
* after AMXX's own.
*
* For more information, see http://wiki.alliedmods.net/Gamedata_Updating_(AMX_Mod_X)
*/
"Games"
{
"#default"
{
"Offsets"
{
"pev"
{
"windows" "4"
"linux" "0"
}
"base"
{
"windows" "0x0"
"linux" "0x60"
}
"spawn"
{
"windows" "0"
"linux" "2"
}
"precache"
{
"windows" "1"
"linux" "3"
}
"keyvalue"
{
"windows" "2"
"linux" "4"
}
"objectcaps"
{
"windows" "5"
"linux" "7"
}
"activate"
{
"windows" "6"
"linux" "8"
}
"setobjectcollisionbox"
{
"windows" "7"
"linux" "9"
}
"classify"
{
"windows" "8"
"linux" "10"
}
"deathnotice"
{
"windows" "9"
"linux" "11"
}
"traceattack"
{
"windows" "10"
"linux" "12"
}
"takedamage"
{
"windows" "11"
"linux" "13"
}
"takehealth"
{
"windows" "12"
"linux" "14"
}
"killed"
{
"windows" "13"
"linux" "15"
}
"bloodcolor"
{
"windows" "14"
"linux" "16"
}
"tracebleed"
{
"windows" "15"
"linux" "17"
}
"istriggered"
{
"windows" "16"
"linux" "18"
}
"mymonsterpointer"
{
"windows" "17"
"linux" "19"
}
"mysquadmonsterpointer"
{
"windows" "18"
"linux" "20"
}
"gettogglestate"
{
"windows" "19"
"linux" "21"
}
"addpoints"
{
"windows" "20"
"linux" "22"
}
"addpointstoteam"
{
"windows" "21"
"linux" "23"
}
"addplayeritem"
{
"windows" "22"
"linux" "24"
}
"removeplayeritem"
{
"windows" "23"
"linux" "25"
}
"getdelay"
{
"windows" "24"
"linux" "26"
}
"ismoving"
{
"windows" "25"
"linux" "27"
}
"overridereset"
{
"windows" "26"
"linux" "28"
}
"damagedecal"
{
"windows" "27"
"linux" "29"
}
"settogglestate"
{
"windows" "28"
"linux" "30"
}
"startsneaking"
{
"windows" "29"
"linux" "31"
}
"stopsneaking"
{
"windows" "30"
"linux" "32"
}
"oncontrols"
{
"windows" "31"
"linux" "33"
}
"issneaking"
{
"windows" "32"
"linux" "34"
}
"isalive"
{
"windows" "33"
"linux" "35"
}
"isbspmodel"
{
"windows" "34"
"linux" "36"
}
"reflectgauss"
{
"windows" "35"
"linux" "37"
}
"hastarget"
{
"windows" "36"
"linux" "38"
}
"isinworld"
{
"windows" "37"
"linux" "39"
}
"isplayer"
{
"windows" "38"
"linux" "40"
}
"isnetclient"
{
"windows" "39"
"linux" "41"
}
"teamid"
{
"windows" "40"
"linux" "42"
}
"getnexttarget"
{
"windows" "41"
"linux" "43"
}
"think"
{
"windows" "42"
"linux" "44"
}
"touch"
{
"windows" "43"
"linux" "45"
}
"use"
{
"windows" "44"
"linux" "46"
}
"blocked"
{
"windows" "45"
"linux" "47"
}
"respawn"
{
"windows" "46"
"linux" "48"
}
"updateowner"
{
"windows" "47"
"linux" "49"
}
"fbecomeprone"
{
"windows" "48"
"linux" "50"
}
"center"
{
"windows" "49"
"linux" "51"
}
"eyeposition"
{
"windows" "50"
"linux" "52"
}
"earposition"
{
"windows" "51"
"linux" "53"
}
"bodytarget"
{
"windows" "52"
"linux" "54"
}
"illumination"
{
"windows" "53"
"linux" "55"
}
"fvisible"
{
"windows" "54"
"linux" "56"
}
"fvecvisible"
{
"windows" "55"
"linux" "57"
}
"look"
{
"windows" "57"
"linux" "59"
}
"changeyaw"
{
"windows" "60"
"linux" "62"
}
"irelationship"
{
"windows" "62"
"linux" "64"
}
"monsterinitdead"
{
"windows" "64"
"linux" "66"
}
"becomedead"
{
"windows" "65"
"linux" "67"
}
"bestvisibleenemy"
{
"windows" "67"
"linux" "69"
}
"finviewcone"
{
"windows" "68"
"linux" "70"
}
"fvecinviewcone"
{
"windows" "69"
"linux" "71"
}
"runai"
{
"windows" "58"
"linux" "60"
}
"monsterthink"
{
"windows" "61"
"linux" "63"
}
"monsterinit"
{
"windows" "63"
"linux" "65"
}
"checklocalmove"
{
"windows" "70"
"linux" "72"
}
"move"
{
"windows" "71"
"linux" "73"
}
"moveexecute"
{
"windows" "72"
"linux" "74"
}
"shouldadvanceroute"
{
"windows" "73"
"linux" "75"
}
"getstoppedactivity"
{
"windows" "74"
"linux" "76"
}
"stop"
{
"windows" "75"
"linux" "77"
}
"checkrangeattack1"
{
"windows" "76"
"linux" "78"
}
"checkrangeattack2"
{
"windows" "77"
"linux" "79"
}
"checkmeleeattack1"
{
"windows" "78"
"linux" "80"
}
"checkmeleeattack2"
{
"windows" "79"
"linux" "81"
}
"schedulechange"
{
"windows" "85"
"linux" "87"
}
"canplaysequence"
{
"windows" "86"
"linux" "88"
}
"canplaysentence"
{
"windows" "87"
"linux" "89"
}
"playsentence"
{
"windows" "88"
"linux" "90"
}
"playscriptedsentence"
{
"windows" "89"
"linux" "91"
}
"sentencestop"
{
"windows" "90"
"linux" "92"
}
"getidealstate"
{
"windows" "91"
"linux" "93"
}
"setactivity"
{
"windows" "92"
"linux" "94"
}
"reportaistate"
{
"windows" "93"
"linux" "95"
}
"checkenemy"
{
"windows" "94"
"linux" "96"
}
"ftriangulate"
{
"windows" "95"
"linux" "97"
}
"setyawspeed"
{
"windows" "96"
"linux" "98"
}
"buildnearestroute"
{
"windows" "97"
"linux" "99"
}
"findcover"
{
"windows" "98"
"linux" "100"
}
"coverradius"
{
"windows" "100"
"linux" "102"
}
"fcancheckattacks"
{
"windows" "101"
"linux" "103"
}
"checkammo"
{
"windows" "102"
"linux" "104"
}
"ignoreconditions"
{
"windows" "103"
"linux" "105"
}
"fvalidatehinttype"
{
"windows" "104"
"linux" "106"
}
"fcanactiveidle"
{
"windows" "105"
"linux" "107"
}
"isoundmask"
{
"windows" "106"
"linux" "108"
}
"hearingsensitivity"
{
"windows" "109"
"linux" "111"
}
"barnaclevictimbitten"
{
"windows" "110"
"linux" "112"
}
"barnaclevictimreleased"
{
"windows" "111"
"linux" "113"
}
"preschedulethink"
{
"windows" "112"
"linux" "114"
}
"getdeathactivity"
{
"windows" "113"
"linux" "115"
}
"gibmonster"
{
"windows" "114"
"linux" "116"
}
"hashumangibs"
{
"windows" "115"
"linux" "117"
}
"hasaliengibs"
{
"windows" "116"
"linux" "118"
}
"fademonster"
{
"windows" "117"
"linux" "119"
}
"deathsound"
{
"windows" "119"
"linux" "121"
}
"alertsound"
{
"windows" "120"
"linux" "122"
}
"idlesound"
{
"windows" "121"
"linux" "123"
}
"painsound"
{
"windows" "122"
"linux" "124"
}
"stopfollowing"
{
"windows" "123"
"linux" "125"
}
"player_jump"
{
"windows" "124"
"linux" "126"
}
"player_prethink"
{
"windows" "125"
"linux" "127"
}
"player_postthink"
{
"windows" "126"
"linux" "128"
}
"player_getgunposition"
{
"windows" "118"
"linux" "120"
}
"player_shouldfadeondeath"
{
"windows" "59"
"linux" "61"
}
"player_impulsecommands"
{
"windows" "128"
"linux" "130"
}
"player_updateclientdata"
{
"windows" "127"
"linux" "129"
}
"item_addtoplayer"
{
"windows" "57"
"linux" "59"
}
"item_addduplicate"
{
"windows" "58"
"linux" "60"
}
"item_getiteminfo"
{
"windows" "59"
"linux" "61"
}
"item_candeploy"
{
"windows" "60"
"linux" "62"
}
"item_deploy"
{
"windows" "61"
"linux" "63"
}
"item_canholster"
{
"windows" "62"
"linux" "64"
}
"item_holster"
{
"windows" "63"
"linux" "65"
}
"item_updateiteminfo"
{
"windows" "64"
"linux" "66"
}
"item_preframe"
{
"windows" "65"
"linux" "67"
}
"item_postframe"
{
"windows" "66"
"linux" "68"
}
"item_drop"
{
"windows" "67"
"linux" "69"
}
"item_kill"
{
"windows" "68"
"linux" "70"
}
"item_attachtoplayer"
{
"windows" "69"
"linux" "71"
}
"item_primaryammoindex"
{
"windows" "70"
"linux" "72"
}
"item_secondaryammoindex"
{
"windows" "71"
"linux" "73"
}
"item_updateclientdata"
{
"windows" "72"
"linux" "74"
}
"item_getweaponptr"
{
"windows" "73"
"linux" "75"
}
"item_itemslot"
{
"windows" "74"
"linux" "76"
}
"weapon_playemptysound"
{
"windows" "75"
"linux" "77"
}
"weapon_resetemptysound"
{
"windows" "76"
"linux" "78"
}
"weapon_sendweaponanim"
{
"windows" "77"
"linux" "79"
}
"weapon_primaryattack"
{
"windows" "78"
"linux" "80"
}
"weapon_secondaryattack"
{
"windows" "79"
"linux" "81"
}
"weapon_weaponidle"
{
"windows" "80"
"linux" "82"
}
"weapon_retireweapon"
{
"windows" "81"
"linux" "83"
}
"weapon_shouldweaponidle"
{
"windows" "82"
"linux" "84"
}
"weapon_usedecrement"
{
"windows" "83"
"linux" "85"
}
"esf_weapon_holsterwhenmeleed"
{
"windows" "84"
"linux" "86"
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,878 @@
/**
* Do not edit this file. Any changes will be overwritten by the gamedata
* updater or by upgrading your AMX Mod X install.
*
* To override data in this file, create a subdirectory named "custom" and
* place your own gamedata file(s) inside of it. Such files will be parsed
* after AMXX's own.
*
* For more information, see http://wiki.alliedmods.net/Gamedata_Updating_(AMX_Mod_X)
*/
"Games"
{
"#default"
{
"Offsets"
{
"pev"
{
"windows" "4"
"linux" "4"
}
"base"
{
"windows" "0x0"
"linux" "0x0"
}
"spawn"
{
"windows" "0"
"linux" "0"
}
"precache"
{
"windows" "1"
"linux" "1"
}
"keyvalue"
{
"windows" "2"
"linux" "2"
}
"objectcaps"
{
"windows" "5"
"linux" "5"
}
"activate"
{
"windows" "6"
"linux" "6"
}
"setobjectcollisionbox"
{
"windows" "7"
"linux" "7"
}
"classify"
{
"windows" "8"
"linux" "8"
}
"deathnotice"
{
"windows" "9"
"linux" "9"
}
"traceattack"
{
"windows" "10"
"linux" "10"
}
"takedamage"
{
"windows" "11"
"linux" "11"
}
"takehealth"
{
"windows" "12"
"linux" "12"
}
"killed"
{
"windows" "14"
"linux" "14"
}
"bloodcolor"
{
"windows" "16"
"linux" "16"
}
"tracebleed"
{
"windows" "17"
"linux" "17"
}
"istriggered"
{
"windows" "18"
"linux" "18"
}
"mymonsterpointer"
{
"windows" "19"
"linux" "19"
}
"mysquadmonsterpointer"
{
"windows" "20"
"linux" "20"
}
"gettogglestate"
{
"windows" "21"
"linux" "21"
}
"addpoints"
{
"windows" "22"
"linux" "22"
}
"addpointstoteam"
{
"windows" "23"
"linux" "23"
}
"addplayeritem"
{
"windows" "24"
"linux" "24"
}
"removeplayeritem"
{
"windows" "25"
"linux" "25"
}
"giveammo"
{
"windows" "26"
"linux" "26"
}
"getdelay"
{
"windows" "27"
"linux" "27"
}
"ismoving"
{
"windows" "28"
"linux" "28"
}
"overridereset"
{
"windows" "29"
"linux" "29"
}
"damagedecal"
{
"windows" "30"
"linux" "30"
}
"settogglestate"
{
"windows" "31"
"linux" "31"
}
"startsneaking"
{
"windows" "32"
"linux" "32"
}
"stopsneaking"
{
"windows" "33"
"linux" "33"
}
"oncontrols"
{
"windows" "34"
"linux" "34"
}
"issneaking"
{
"windows" "35"
"linux" "35"
}
"isalive"
{
"windows" "36"
"linux" "36"
}
"isbspmodel"
{
"windows" "37"
"linux" "37"
}
"reflectgauss"
{
"windows" "38"
"linux" "38"
}
"hastarget"
{
"windows" "39"
"linux" "39"
}
"isinworld"
{
"windows" "40"
"linux" "40"
}
"isplayer"
{
"windows" "41"
"linux" "41"
}
"isnetclient"
{
"windows" "42"
"linux" "42"
}
"teamid"
{
"windows" "43"
"linux" "43"
}
"getnexttarget"
{
"windows" "46"
"linux" "46"
}
"think"
{
"windows" "47"
"linux" "47"
}
"touch"
{
"windows" "48"
"linux" "48"
}
"use"
{
"windows" "49"
"linux" "49"
}
"blocked"
{
"windows" "50"
"linux" "50"
}
"respawn"
{
"windows" "52"
"linux" "52"
}
"updateowner"
{
"windows" "53"
"linux" "53"
}
"fbecomeprone"
{
"windows" "54"
"linux" "54"
}
"center"
{
"windows" "55"
"linux" "55"
}
"eyeposition"
{
"windows" "56"
"linux" "56"
}
"earposition"
{
"windows" "57"
"linux" "57"
}
"bodytarget"
{
"windows" "58"
"linux" "58"
}
"illumination"
{
"windows" "59"
"linux" "59"
}
"fvisible"
{
"windows" "60"
"linux" "60"
}
"fvecvisible"
{
"windows" "61"
"linux" "61"
}
"changeyaw"
{
"windows" "65"
"linux" "65"
}
"hashumangibs"
{
"windows" "66"
"linux" "66"
}
"hasaliengibs"
{
"windows" "67"
"linux" "67"
}
"fademonster"
{
"windows" "68"
"linux" "68"
}
"gibmonster"
{
"windows" "69"
"linux" "69"
}
"getdeathactivity"
{
"windows" "70"
"linux" "70"
}
"becomedead"
{
"windows" "71"
"linux" "71"
}
"irelationship"
{
"windows" "73"
"linux" "73"
}
"painsound"
{
"windows" "74"
"linux" "74"
}
"reportaistate"
{
"windows" "75"
"linux" "75"
}
"monsterinitdead"
{
"windows" "76"
"linux" "76"
}
"look"
{
"windows" "77"
"linux" "77"
}
"bestvisibleenemy"
{
"windows" "78"
"linux" "78"
}
"finviewcone"
{
"windows" "80"
"linux" "80"
}
"fvecinviewcone"
{
"windows" "81"
"linux" "81"
}
"player_jump"
{
"windows" "83"
"linux" "83"
}
"player_duck"
{
"windows" "84"
"linux" "84"
}
"player_prethink"
{
"windows" "85"
"linux" "85"
}
"player_postthink"
{
"windows" "86"
"linux" "86"
}
"player_getgunposition"
{
"windows" "87"
"linux" "87"
}
"player_shouldfadeondeath"
{
"windows" "72"
"linux" "72"
}
"player_impulsecommands"
{
"windows" "101"
"linux" "101"
}
"player_updateclientdata"
{
"windows" "99"
"linux" "99"
}
"item_addtoplayer"
{
"windows" "64"
"linux" "64"
}
"item_addduplicate"
{
"windows" "65"
"linux" "65"
}
"item_getiteminfo"
{
"windows" "68"
"linux" "68"
}
"item_candeploy"
{
"windows" "69"
"linux" "69"
}
"item_deploy"
{
"windows" "70"
"linux" "70"
}
"item_canholster"
{
"windows" "71"
"linux" "71"
}
"item_holster"
{
"windows" "72"
"linux" "72"
}
"item_updateiteminfo"
{
"windows" "74"
"linux" "74"
}
"item_preframe"
{
"windows" "75"
"linux" "75"
}
"item_postframe"
{
"windows" "76"
"linux" "76"
}
"item_drop"
{
"windows" "77"
"linux" "77"
}
"item_kill"
{
"windows" "78"
"linux" "78"
}
"item_attachtoplayer"
{
"windows" "79"
"linux" "79"
}
"item_primaryammoindex"
{
"windows" "80"
"linux" "80"
}
"item_secondaryammoindex"
{
"windows" "81"
"linux" "81"
}
"item_updateclientdata"
{
"windows" "82"
"linux" "82"
}
"item_getweaponptr"
{
"windows" "83"
"linux" "83"
}
"item_itemslot"
{
"windows" "84"
"linux" "84"
}
"weapon_extractammo"
{
"windows" "85"
"linux" "85"
}
"weapon_extractclipammo"
{
"windows" "86"
"linux" "86"
}
"weapon_addweapon"
{
"windows" "87"
"linux" "87"
}
"weapon_playemptysound"
{
"windows" "88"
"linux" "88"
}
"weapon_resetemptysound"
{
"windows" "89"
"linux" "89"
}
"weapon_sendweaponanim"
{
"windows" "94"
"linux" "94"
}
"weapon_isusable"
{
"windows" "73"
"linux" "73"
}
"weapon_primaryattack"
{
"windows" "98"
"linux" "98"
}
"weapon_secondaryattack"
{
"windows" "99"
"linux" "99"
}
"weapon_reload"
{
"windows" "100"
"linux" "100"
}
"weapon_weaponidle"
{
"windows" "101"
"linux" "101"
}
"weapon_retireweapon"
{
"windows" "102"
"linux" "102"
}
"weapon_shouldweaponidle"
{
"windows" "103"
"linux" "103"
}
"weapon_usedecrement"
{
"windows" "104"
"linux" "104"
}
"ns_getpointvalue"
{
"windows" "13"
"linux" "13"
}
"ns_awardkill"
{
"windows" "15"
"linux" "15"
}
"ns_resetentity"
{
"windows" "45"
"linux" "45"
}
"ns_updateonremove"
{
"windows" "51"
"linux" "51"
}
"ns_setbonecontroller"
{
"windows" "63"
"linux" "63"
}
"ns_savedataforreset"
{
"windows" "64"
"linux" "64"
}
"ns_gethull"
{
"windows" "79"
"linux" "79"
}
"ns_getmaxwalkspeed"
{
"windows" "88"
"linux" "88"
}
"ns_setteamid"
{
"windows" "90"
"linux" "90"
}
"ns_geteffectiveplayerclass"
{
"windows" "91"
"linux" "91"
}
"ns_getauthenticationmask"
{
"windows" "92"
"linux" "92"
}
"ns_effectiveplayerclasschanged"
{
"windows" "93"
"linux" "93"
}
"ns_needsteamupdate"
{
"windows" "94"
"linux" "94"
}
"ns_sendteamupdate"
{
"windows" "95"
"linux" "95"
}
"ns_sendweaponupdate"
{
"windows" "96"
"linux" "96"
}
"ns_initplayerfromspawn"
{
"windows" "97"
"linux" "97"
}
"ns_packdeadplayeritems"
{
"windows" "98"
"linux" "98"
}
"ns_getanimationforactivity"
{
"windows" "100"
"linux" "100"
}
"ns_startobserver"
{
"windows" "102"
"linux" "102"
}
"ns_stopobserver"
{
"windows" "103"
"linux" "103"
}
"ns_getadrenalinefactor"
{
"windows" "104"
"linux" "104"
}
"ns_givenameditem"
{
"windows" "106"
"linux" "106"
}
"ns_suicide"
{
"windows" "107"
"linux" "107"
}
"ns_getcanuseweapon"
{
"windows" "108"
"linux" "108"
}
"ns_weapon_getweaponprimetime"
{
"windows" "90"
"linux" "90"
}
"ns_weapon_primeweapon"
{
"windows" "91"
"linux" "91"
}
"ns_weapon_getisweaponprimed"
{
"windows" "92"
"linux" "92"
}
"ns_weapon_getisweaponpriming"
{
"windows" "93"
"linux" "93"
}
"ns_weapon_defaultdeploy"
{
"windows" "95"
"linux" "95"
}
"ns_weapon_defaultreload"
{
"windows" "96"
"linux" "96"
}
"ns_weapon_getdeploytime"
{
"windows" "97"
"linux" "97"
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,746 @@
/**
* Do not edit this file. Any changes will be overwritten by the gamedata
* updater or by upgrading your AMX Mod X install.
*
* To override data in this file, create a subdirectory named "custom" and
* place your own gamedata file(s) inside of it. Such files will be parsed
* after AMXX's own.
*
* For more information, see http://wiki.alliedmods.net/Gamedata_Updating_(AMX_Mod_X)
*/
"Games"
{
"#default"
{
"Offsets"
{
"pev"
{
"windows" "4"
"linux" "0"
}
"base"
{
"windows" "0x0"
"linux" "0x60"
}
"spawn"
{
"windows" "7"
"linux" "9"
}
"precache"
{
"windows" "8"
"linux" "10"
}
"keyvalue"
{
"windows" "9"
"linux" "11"
}
"objectcaps"
{
"windows" "12"
"linux" "14"
}
"activate"
{
"windows" "13"
"linux" "15"
}
"setobjectcollisionbox"
{
"windows" "16"
"linux" "18"
}
"classify"
{
"windows" "17"
"linux" "19"
}
"deathnotice"
{
"windows" "18"
"linux" "20"
}
"traceattack"
{
"windows" "19"
"linux" "21"
}
"takedamage"
{
"windows" "20"
"linux" "22"
}
"takehealth"
{
"windows" "21"
"linux" "23"
}
"killed"
{
"windows" "22"
"linux" "24"
}
"bloodcolor"
{
"windows" "23"
"linux" "25"
}
"tracebleed"
{
"windows" "24"
"linux" "26"
}
"istriggered"
{
"windows" "25"
"linux" "27"
}
"mymonsterpointer"
{
"windows" "26"
"linux" "28"
}
"mysquadmonsterpointer"
{
"windows" "27"
"linux" "29"
}
"gettogglestate"
{
"windows" "28"
"linux" "30"
}
"addpoints"
{
"windows" "29"
"linux" "31"
}
"addpointstoteam"
{
"windows" "30"
"linux" "32"
}
"addplayeritem"
{
"windows" "31"
"linux" "33"
}
"removeplayeritem"
{
"windows" "32"
"linux" "34"
}
"giveammo"
{
"windows" "33"
"linux" "35"
}
"getdelay"
{
"windows" "34"
"linux" "36"
}
"ismoving"
{
"windows" "35"
"linux" "37"
}
"overridereset"
{
"windows" "36"
"linux" "38"
}
"damagedecal"
{
"windows" "37"
"linux" "39"
}
"settogglestate"
{
"windows" "38"
"linux" "40"
}
"startsneaking"
{
"windows" "39"
"linux" "41"
}
"stopsneaking"
{
"windows" "40"
"linux" "42"
}
"oncontrols"
{
"windows" "41"
"linux" "43"
}
"issneaking"
{
"windows" "42"
"linux" "44"
}
"isalive"
{
"windows" "43"
"linux" "45"
}
"isbspmodel"
{
"windows" "44"
"linux" "46"
}
"reflectgauss"
{
"windows" "45"
"linux" "47"
}
"hastarget"
{
"windows" "46"
"linux" "48"
}
"isinworld"
{
"windows" "47"
"linux" "49"
}
"isplayer"
{
"windows" "48"
"linux" "50"
}
"isnetclient"
{
"windows" "49"
"linux" "51"
}
"teamid"
{
"windows" "50"
"linux" "52"
}
"getnexttarget"
{
"windows" "51"
"linux" "53"
}
"think"
{
"windows" "52"
"linux" "54"
}
"touch"
{
"windows" "53"
"linux" "55"
}
"use"
{
"windows" "54"
"linux" "56"
}
"blocked"
{
"windows" "55"
"linux" "57"
}
"respawn"
{
"windows" "57"
"linux" "59"
}
"updateowner"
{
"windows" "58"
"linux" "60"
}
"fbecomeprone"
{
"windows" "59"
"linux" "61"
}
"center"
{
"windows" "60"
"linux" "62"
}
"eyeposition"
{
"windows" "61"
"linux" "63"
}
"earposition"
{
"windows" "62"
"linux" "64"
}
"bodytarget"
{
"windows" "63"
"linux" "65"
}
"illumination"
{
"windows" "64"
"linux" "66"
}
"fvisible"
{
"windows" "65"
"linux" "67"
}
"fvecvisible"
{
"windows" "66"
"linux" "68"
}
"changeyaw"
{
"windows" "68"
"linux" "70"
}
"hashumangibs"
{
"windows" "69"
"linux" "71"
}
"hasaliengibs"
{
"windows" "70"
"linux" "72"
}
"fademonster"
{
"windows" "71"
"linux" "73"
}
"gibmonster"
{
"windows" "72"
"linux" "74"
}
"getdeathactivity"
{
"windows" "73"
"linux" "75"
}
"becomedead"
{
"windows" "74"
"linux" "76"
}
"irelationship"
{
"windows" "76"
"linux" "78"
}
"painsound"
{
"windows" "77"
"linux" "79"
}
"reportaistate"
{
"windows" "78"
"linux" "80"
}
"monsterinitdead"
{
"windows" "79"
"linux" "81"
}
"look"
{
"windows" "80"
"linux" "82"
}
"bestvisibleenemy"
{
"windows" "81"
"linux" "83"
}
"finviewcone"
{
"windows" "82"
"linux" "84"
}
"fvecinviewcone"
{
"windows" "83"
"linux" "85"
}
"player_jump"
{
"windows" "84"
"linux" "86"
}
"player_duck"
{
"windows" "85"
"linux" "87"
}
"player_prethink"
{
"windows" "86"
"linux" "88"
}
"player_postthink"
{
"windows" "87"
"linux" "89"
}
"player_getgunposition"
{
"windows" "88"
"linux" "90"
}
"player_shouldfadeondeath"
{
"windows" "75"
"linux" "77"
}
"player_impulsecommands"
{
"windows" "90"
"linux" "92"
}
"player_updateclientdata"
{
"windows" "89"
"linux" "91"
}
"item_addtoplayer"
{
"windows" "68"
"linux" "70"
}
"item_addduplicate"
{
"windows" "69"
"linux" "71"
}
"item_candeploy"
{
"windows" "71"
"linux" "73"
}
"item_deploy"
{
"windows" "72"
"linux" "74"
}
"item_canholster"
{
"windows" "73"
"linux" "75"
}
"item_holster"
{
"windows" "74"
"linux" "76"
}
"item_updateiteminfo"
{
"windows" "75"
"linux" "77"
}
"item_preframe"
{
"windows" "76"
"linux" "78"
}
"item_postframe"
{
"windows" "77"
"linux" "79"
}
"item_drop"
{
"windows" "78"
"linux" "80"
}
"item_kill"
{
"windows" "79"
"linux" "81"
}
"item_attachtoplayer"
{
"windows" "80"
"linux" "82"
}
"item_primaryammoindex"
{
"windows" "81"
"linux" "83"
}
"item_secondaryammoindex"
{
"windows" "82"
"linux" "84"
}
"item_updateclientdata"
{
"windows" "83"
"linux" "85"
}
"item_getweaponptr"
{
"windows" "84"
"linux" "86"
}
"item_itemslot"
{
"windows" "85"
"linux" "87"
}
"weapon_extractammo"
{
"windows" "86"
"linux" "88"
}
"weapon_extractclipammo"
{
"windows" "87"
"linux" "89"
}
"weapon_addweapon"
{
"windows" "88"
"linux" "90"
}
"weapon_playemptysound"
{
"windows" "89"
"linux" "91"
}
"weapon_resetemptysound"
{
"windows" "90"
"linux" "92"
}
"weapon_sendweaponanim"
{
"windows" "91"
"linux" "93"
}
"weapon_isusable"
{
"windows" "92"
"linux" "94"
}
"weapon_primaryattack"
{
"windows" "93"
"linux" "95"
}
"weapon_secondaryattack"
{
"windows" "94"
"linux" "96"
}
"weapon_reload"
{
"windows" "96"
"linux" "98"
}
"weapon_weaponidle"
{
"windows" "97"
"linux" "99"
}
"weapon_retireweapon"
{
"windows" "98"
"linux" "100"
}
"weapon_shouldweaponidle"
{
"windows" "99"
"linux" "101"
}
"weapon_usedecrement"
{
"windows" "100"
"linux" "102"
}
"ts_breakablerespawn"
{
"windows" "0"
"linux" "2"
}
"ts_canusedthroughwalls"
{
"windows" "1"
"linux" "3"
}
"ts_giveslowmul"
{
"windows" "2"
"linux" "4"
}
"ts_goslow"
{
"windows" "3"
"linux" "5"
}
"ts_inslow"
{
"windows" "4"
"linux" "6"
}
"ts_isobjective"
{
"windows" "5"
"linux" "7"
}
"ts_enableobjective"
{
"windows" "6"
"linux" "8"
}
"ts_onfreeentprivatedata"
{
"windows" "10"
"linux" "12"
}
"ts_shouldcollide"
{
"windows" "11"
"linux" "13"
}
"ts_weapon_alternateattack"
{
"windows" "95"
"linux" "97"
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -110,7 +110,6 @@ Section "MainSection" SEC01
File "installer\files\base\addons\amxmodx\configs\core.ini"
File "installer\files\base\addons\amxmodx\configs\custommenuitems.cfg"
File "installer\files\base\addons\amxmodx\configs\cvars.ini"
File "installer\files\base\addons\amxmodx\configs\hamdata.ini"
File "installer\files\base\addons\amxmodx\configs\maps.ini"
File "installer\files\base\addons\amxmodx\configs\modules.ini"
File "installer\files\base\addons\amxmodx\configs\plugins.ini"

View File

@ -25,5 +25,9 @@ binary.sources = [
if builder.target_platform == 'windows':
binary.sources += ['version.rc']
binary.compiler.linkflags += [
'/EXPORT:GiveFnptrsToDll=_GiveFnptrsToDll@8,@1',
'/SECTION:.data,RW',
]
AMXX.modules += [builder.Add(binary)]

View File

@ -721,9 +721,9 @@ void InitFuncsAddresses()
MF_Log("UTIL_FindEntByString is not available - native cs_find_ent_by_class() has been disabled");
}
if (!AddEntityHashValue || !AddEntityHashValue)
if (!AddEntityHashValue || !RemoveEntityHashValue)
{
MF_Log("AddEntityHashValue or AddEntityHashValue is not available - native cs_set_ent_class() has been disabled");
MF_Log("AddEntityHashValue or RemoveEntityHashValue is not available - native cs_set_ent_class() has been disabled");
}
if (!HasReGameDll && !GetWeaponInfo)
@ -735,6 +735,7 @@ void InitFuncsAddresses()
void InitClassMembers()
{
// CBasePlayer members.
CommonConfig->GetOffsetByClass("CBasePlayer", "m_iTeam" , &TeamDesc );
CommonConfig->GetOffsetByClass("CBasePlayer", "m_iMenu" , &MenuDesc );
CommonConfig->GetOffsetByClass("CBasePlayer", "m_bHasNightVision", &NvgsDesc );
@ -742,12 +743,16 @@ void InitClassMembers()
CommonConfig->GetOffsetByClass("CBasePlayer", "m_signals" , &SignalsDesc);
CommonConfig->GetOffsetByClass("CBasePlayer", "m_iAccount" , &MoneyDesc );
// GameRules members.
CommonConfig->GetOffsetByClass("CHalfLifeMultiplay", "m_bMapHasBombTarget", &BombTargetDesc);
if (!TeamDesc.fieldOffset ||
!MenuDesc.fieldOffset ||
!NvgsDesc.fieldOffset ||
!DefuserDesc.fieldOffset ||
!SignalsDesc.fieldOffset ||
!MoneyDesc.fieldOffset)
!MoneyDesc.fieldOffset ||
!BombTargetDesc.fieldOffset)
{
MF_Log("Invalid or missing entity gamedata files - forwards CS_OnBuy[Attempt] have been disabled");
ToggleHook_BuyCommands(false);

View File

@ -17,7 +17,7 @@
#include <resdk/mod_regamedll_api.h>
CsItemInfo ItemsManager;
ItemInfo WeaponsList[MAX_WEAPONS];
ItemInfos WeaponsList[MAX_WEAPONS];
#define PSTATE_ALIASES_TYPE 0
#define PSTATE_ALIASES_ALIAS 1

View File

@ -20,12 +20,12 @@
#include <amtl/am-string.h>
#include <sm_stringhashmap.h>
struct ItemInfo
struct ItemInfos
{
ItemInfo() : name("Empty"), ammoIndex1(-1), maxAmmo1(0), ammoIndex2(-1), maxAmmo2(0), slot(0), position(0), id(0), flags(0)
ItemInfos() : name("Empty"), ammoIndex1(-1), maxAmmo1(0), ammoIndex2(-1), maxAmmo2(0), slot(0), position(0), id(0), flags(0)
{}
ItemInfo &operator = (ItemInfo &other)
ItemInfos &operator = (ItemInfos &other)
{
name = other.name;
ammoIndex1 = other.ammoIndex1;
@ -133,7 +133,7 @@ class CsItemInfo : public ITextListener_SMC
int m_EquipmentsPrice[static_cast<size_t>(Equipments::Count)];
};
extern ItemInfo WeaponsList[MAX_WEAPONS];
extern ItemInfos WeaponsList[MAX_WEAPONS];
extern CsItemInfo ItemsManager;
#endif // _CSTRIKE_WEAPONS_INFOS_H_

View File

@ -37,30 +37,6 @@ int AmxxCheckGame(const char *game)
return AMXX_GAME_BAD;
}
void SV_ActivateServer_RH(IRehldsHook_SV_ActivateServer *chain, int runPhysics)
{
chain->callNext(runPhysics);
auto numResources = RehldsData->GetResourcesNum();
if (!numResources)
{
return;
}
ModelsList.clear();
for (auto i = 0; i < numResources; ++i) // Saves all the precached models into a list.
{
auto resource = RehldsData->GetResource(i);
if (resource->type == t_model)
{
ModelsList.insert(resource->szFileName, i);
}
}
}
void OnAmxxAttach()
{
MF_AddNatives(CstrikeNatives);
@ -85,11 +61,6 @@ void OnAmxxAttach()
}
InitializeHacks();
if (HasReHlds)
{
RehldsHookchains->SV_ActivateServer()->registerHook(SV_ActivateServer_RH);
}
}
void OnPluginsLoaded()
@ -131,6 +102,8 @@ void OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
ToggleHook_BuyCommands(HasOnBuyForward);
ToggleHook_GiveDefaultItems(false);
ModelsList.clear();
RETURN_META(MRES_IGNORED);
}

View File

@ -856,15 +856,33 @@ static cell AMX_NATIVE_CALL cs_set_user_model(AMX *amx, cell *params)
if (*params / sizeof(cell) >= 3 && params[3] != 0)
{
if (!Server)
if (!HasReHlds && !Server)
{
MF_Log("cs_set_user_model is disabled with update_index parameter set");
return 0;
}
if (!ModelsList.elements())
{
auto numResources = HasReHlds ? RehldsData->GetResourcesNum() : Server->num_resources;
if (numResources)
{
for (auto i = 0; i < numResources; ++i) // Saves all the precached models into a list.
{
auto resource = HasReHlds ? RehldsData->GetResource(i) : &Server->resourcelist[i];
if (resource->type == t_model)
{
ModelsList.insert(resource->szFileName, resource->nIndex);
}
}
}
}
GET_OFFSET("CBasePlayer", m_modelIndexPlayer);
char modelpath[260];
char modelpath[PLATFORM_MAX_PATH];
ke::SafeSprintf(modelpath, sizeof(modelpath), "models/player/%s/%s.mdl", newModel, newModel);
auto modelIndex = 0;
@ -1663,7 +1681,7 @@ static cell AMX_NATIVE_CALL cs_set_c4_defusing(AMX* amx, cell* params)
// cs_create_entity(const classname[])
static cell AMX_NATIVE_CALL cs_create_entity(AMX* amx, cell* params)
{
if (CS_CreateNamedEntity <= 0)
if (!CS_CreateNamedEntity)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Native cs_create_entity() is disabled. Check your amxx logs.");
return 0;
@ -1685,7 +1703,7 @@ static cell AMX_NATIVE_CALL cs_create_entity(AMX* amx, cell* params)
// cs_find_ent_by_class(start_index, const classname[])
static cell AMX_NATIVE_CALL cs_find_ent_by_class(AMX* amx, cell* params)
{
if (CS_UTIL_FindEntityByString <= 0)
if (!CS_UTIL_FindEntityByString)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Native cs_find_ent_by_class() is disabled. Check your amxx logs.");
return 0;
@ -1708,7 +1726,7 @@ static cell AMX_NATIVE_CALL cs_find_ent_by_class(AMX* amx, cell* params)
// cs_find_ent_by_owner(start_index, const classname[], owner)
static cell AMX_NATIVE_CALL cs_find_ent_by_owner(AMX* amx, cell* params)
{
if (CS_UTIL_FindEntityByString <= 0)
if (!CS_UTIL_FindEntityByString)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Native cs_find_ent_by_owner() is disabled. Check your amxx logs.");
return 0;
@ -1744,7 +1762,7 @@ static cell AMX_NATIVE_CALL cs_find_ent_by_owner(AMX* amx, cell* params)
// cs_set_ent_class(index, const classname[])
static cell AMX_NATIVE_CALL cs_set_ent_class(AMX* amx, cell* params)
{
if (AddEntityHashValue <= 0 || RemoveEntityHashValue <= 0)
if (!AddEntityHashValue || !RemoveEntityHashValue)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Native cs_set_ent_class() is disabled. Check your amxx logs.");
return 0;
@ -1876,7 +1894,7 @@ static cell AMX_NATIVE_CALL cs_get_translated_item_alias(AMX* amx, cell* params)
// native cs_get_weapon_info(weapon_id, CsWeaponInfo:type);
static cell AMX_NATIVE_CALL cs_get_weapon_info(AMX* amx, cell* params)
{
if (!HasReGameDll && GetWeaponInfo <= 0)
if (!HasReGameDll && !GetWeaponInfo)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Native cs_get_weapon_info() is disabled. Check your amxx logs.");
return 0;
@ -1980,6 +1998,34 @@ static cell AMX_NATIVE_CALL cs_get_user_weapon(AMX *amx, cell *params)
return 0;
}
// native cs_get_weaponbox_item(weaponboxIndex);
static cell AMX_NATIVE_CALL cs_get_weaponbox_item(AMX *amx, cell *params)
{
GET_OFFSET("CWeaponBox", m_rgpPlayerItems);
int weaponboxIndex = params[1];
CHECK_NONPLAYER(weaponboxIndex);
edict_t *pWeaponBox = TypeConversion.id_to_edict(weaponboxIndex);
if (strcmp(STRING(pWeaponBox->v.classname), "weaponbox") != 0)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Not a weaponbox entity! (%d)", weaponboxIndex);
return 0;
}
edict_t *pWeapon;
for (int i = 1; i < MAX_ITEM_TYPES; i++)
{
pWeapon = TypeConversion.cbase_to_edict(get_pdata<void *>(pWeaponBox, m_rgpPlayerItems, i));
if (!FNullEnt(pWeapon))
{
return TypeConversion.edict_to_id(pWeapon);
}
}
return 0;
}
AMX_NATIVE_INFO CstrikeNatives[] =
{
{"cs_set_user_money", cs_set_user_money},
@ -2052,5 +2098,6 @@ AMX_NATIVE_INFO CstrikeNatives[] =
{"cs_get_weapon_info", cs_get_weapon_info},
{"cs_get_user_weapon_entity", cs_get_user_weapon_entity},
{"cs_get_user_weapon", cs_get_user_weapon},
{"cs_get_weaponbox_item", cs_get_weaponbox_item},
{nullptr, nullptr}
};

View File

@ -22,7 +22,7 @@ bool ShouldBlock;
bool ShouldBlockHLTV;
bool ShouldDisableHooks;
bool RetrieveWeaponList;
ItemInfo CurrentWeaponList;
ItemInfos CurrentWeaponList;
int ArgPosition;
int MessageIdArmorType;

View File

@ -13,12 +13,13 @@
#include "amxxmodule.h"
#include <amtl/am-algorithm.h>
#include <amtl/am-string.h>
extern int MessageIdTextMsg;
bool UTIL_IsPlayer(edict_t *pPlayer)
{
return strcmp(STRING(pPlayer->v.classname), "player") == 0;
return pPlayer && strcmp(STRING(pPlayer->v.classname), "player") == 0;
}
void UTIL_TextMsg_Generic(edict_t* pPlayer, const char* message)
@ -36,7 +37,7 @@ bool UTIL_CheckForPublic(const char *publicname)
int i = 0;
char blah[64];
strncpy(blah, publicname, sizeof(blah) - 1);
ke::SafeStrcpy(blah, sizeof(blah), publicname);
while ((amx = MF_GetScriptAmx(i++)))
{

View File

@ -49,6 +49,10 @@ void UTIL_StringToLower(const char *str, char *buffer, size_t maxlength);
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid player %d (not in-game)", x); \
return 0; \
} \
else if (!MF_GetPlayerEdict(x)->pvPrivateData) { \
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid player %d (no private data)", x); \
return 0; \
} \
} else { \
if (x != 0 && FNullEnt(TypeConversion.id_to_edict(x))) { \
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid entity %d", x); \
@ -62,8 +66,12 @@ void UTIL_StringToLower(const char *str, char *buffer, size_t maxlength);
MF_LogError(amx, AMX_ERR_NATIVE, "Player out of range (%d)", x); \
return 0; \
} else { \
if (!MF_IsPlayerIngame(x) || FNullEnt(MF_GetPlayerEdict(x))) { \
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid player %d", x); \
if (!MF_IsPlayerIngame(x)) { \
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid player %d (not in-game)", x); \
return 0; \
} \
else if (!MF_GetPlayerEdict(x)->pvPrivateData) { \
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid player %d (no private data)", x); \
return 0; \
} \
}

View File

@ -25,7 +25,7 @@
#define MODULE_LIBRARY "cstrike"
#define MODULE_LIBCLASS ""
// If you want the module not to be reloaded on mapchange, remove / comment out the next line
#define MODULE_RELOAD_ON_MAPCHANGE
// #define MODULE_RELOAD_ON_MAPCHANGE
#ifdef __DATE__
#define MODULE_DATE __DATE__

View File

@ -95,6 +95,8 @@
<SubSystem>Windows</SubSystem>
<IgnoreSpecificDefaultLibraries>LIBCMT;</IgnoreSpecificDefaultLibraries>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalOptions>/EXPORT:GiveFnptrsToDll=_GiveFnptrsToDll@8,@1 %(AdditionalOptions)</AdditionalOptions>
<SpecifySectionAttributes>.data,RW</SpecifySectionAttributes>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -138,6 +140,8 @@
<ImportLibrary>.\Release/cstrike_amx.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<SubSystem>Windows</SubSystem>
<AdditionalOptions>/EXPORT:GiveFnptrsToDll=_GiveFnptrsToDll@8,@1 %(AdditionalOptions)</AdditionalOptions>
<SpecifySectionAttributes>.data,RW</SpecifySectionAttributes>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
@ -161,9 +165,18 @@
<ClInclude Include="..\..\..\..\public\memtools\CDetour\detours.h" />
<ClInclude Include="..\..\..\..\public\memtools\MemoryUtils.h" />
<ClInclude Include="..\..\..\..\public\resdk\common\hookchains.h" />
<ClInclude Include="..\..\..\..\public\resdk\cstrike\API\CSEntity.h" />
<ClInclude Include="..\..\..\..\public\resdk\cstrike\API\CSInterfaces.h" />
<ClInclude Include="..\..\..\..\public\resdk\cstrike\API\CSPlayer.h" />
<ClInclude Include="..\..\..\..\public\resdk\cstrike\API\CSPlayerItem.h" />
<ClInclude Include="..\..\..\..\public\resdk\cstrike\API\CSPlayerWeapon.h" />
<ClInclude Include="..\..\..\..\public\resdk\cstrike\regamedll_api.h" />
<ClInclude Include="..\..\..\..\public\resdk\cstrike\regamedll_const.h" />
<ClInclude Include="..\..\..\..\public\resdk\cstrike\regamedll_interfaces.h" />
<ClInclude Include="..\..\..\..\public\resdk\engine\cmd_rehlds.h" />
<ClInclude Include="..\..\..\..\public\resdk\engine\FlightRecorder.h" />
<ClInclude Include="..\..\..\..\public\resdk\engine\IObjectContainer.h" />
<ClInclude Include="..\..\..\..\public\resdk\engine\ObjectList.h" />
<ClInclude Include="..\..\..\..\public\resdk\engine\pr_dlls.h" />
<ClInclude Include="..\..\..\..\public\resdk\engine\rehlds_api.h" />
<ClInclude Include="..\..\..\..\public\resdk\engine\rehlds_interfaces.h" />
<ClInclude Include="..\..\..\..\public\resdk\mod_regamedll_api.h" />
@ -181,6 +194,12 @@
<None Include="..\..\..\..\plugins\include\cstrike.inc" />
<None Include="..\..\..\..\plugins\include\cstrike_const.inc" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\version.rc">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../../../public;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../../../public;</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

Some files were not shown because too many files have changed in this diff Show More