Compare commits

...

29 Commits

Author SHA1 Message Date
Xackery b83fafb745 Added new dependency structure support. 2018-07-05 10:11:02 -07:00
Xackery bcc42edb16 added a gitignore entry for docker/db 2018-03-23 14:50:00 -07:00
Xackery 0eba5f2990 BT changed to BodyType, revised MessageType listings 2018-03-23 14:49:40 -07:00
Xackery c70bdc6b70 Repaired bug with guild chat 2018-03-21 14:39:14 -07:00
Xackery 6a25f30441 Added lua/perl support for nats AdminMessage, added more response fields 2018-03-17 18:45:31 -07:00
Xackery 825dbc9e9a Updated nats examples 2018-03-16 18:43:14 -07:00
Xackery a5f35bf32a Added partial OP_NewZone support 2018-03-15 15:54:31 -07:00
Xackery c09ab507dd Added opcode support for aaaction, aaexpupdate, zonecompleted. 2018-03-14 13:54:08 -07:00
Xackery 483ca9996b world/nats_message now properly uses byte for serializing 2018-03-14 13:22:12 -07:00
Xackery 122f1cd02d zone/natsmanager now properly uses byte for serializing 2018-03-14 12:02:39 -07:00
Xackery e0d4f9ecd1 Added door properties, and more entitylist types 2018-03-14 11:30:58 -07:00
Xackery cb72ad4d0f Added EncodeEntity 2018-03-13 22:02:33 -07:00
Xackery 98f4e570e7 Added MessageType and SpecialMessage support 2018-03-13 17:39:44 -07:00
Xackery 6532a81b80 Massive overhaul on zone/nats_manager 2018-03-13 15:29:28 -07:00
Xackery b0f591540c fixed minor typo 2018-03-13 00:24:06 -07:00
Xackery ac07e7d578 Cleaned up zone/nats_manager logic 2018-03-12 20:44:13 -07:00
Xackery 40ef387496 Added proper support for arena in nats_manager, misc cleanup 2018-03-12 10:00:00 -07:00
Xackery c9a79af79b Removed unused dailygain 2018-03-11 22:35:21 -07:00
Xackery 1a71237dc2 Protobuf is now module cmake loaded on linux, and generates files on build 2018-03-11 22:27:37 -07:00
Xackery f990292660 Removed the custom /deploy/server cmake config 2018-03-11 14:20:50 -07:00
Xackery e72f1e855f added csharp helloworld nats example 2018-03-10 22:34:48 -08:00
Xackery 3bc9e4bc24 Added python example 2018-03-10 19:47:02 -08:00
Xackery 22aef8ad79 Changed helloworld.go to use proper import 2018-03-10 18:44:01 -08:00
Xackery bf84fcd908 Added helloworld go example, repaired SendChannelMessage in world 2018-03-10 18:37:48 -08:00
Xackery 0c5779d2de Cleaned up channel message styles 2018-03-10 14:25:43 -08:00
Xackery 2270bd267d Merge branch 'master' into nats
# Conflicts:
#	world/client.cpp
#	zone/attack.cpp
#	zone/map.cpp
#	zone/map.h
#	zone/spells.cpp
2018-03-10 13:59:48 -08:00
Xackery feec425be9 Merge branch 'master' into nats
Conflicts:
	zone/loottables.cpp
2018-02-16 15:11:21 -08:00
Xackery dd5ef6523f repaired dependency issues for protobuf 2018-02-11 13:24:03 -08:00
Xackery c69b9a95b7 Nats initial commit 2018-02-10 23:42:38 -08:00
69 changed files with 16922 additions and 131 deletions
+17 -10
View File
@@ -23,17 +23,24 @@ CMakeFiles
Makefile
cmake_install.cmake
install_manifest.txt
Build/
build/
Build32/
build32/
Build64/
build64/
Build_32/
build_32/
Build_64/
build_64/
[Bb]uild/
[Bb]uild32/
[Bb]uild64/
[Bb]uild_32/
[Bb]uild_64/
deploy/server/
x64/
x86/
log/
logs/
docker/db
# Protobuf generated files
*.pb.cc
*.pb.h
protobuf/csharp/*
protobuf/go/*
protobuf/java/*
protobuf/python/*
.vscode
+75 -2
View File
@@ -29,7 +29,7 @@
#We set a fairly new version (as of 2013) because I found finding perl was a bit... buggy on older ones
#Can change this if you really want but you should upgrade!
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12)
#FindMySQL is located here so lets make it so CMake can find it
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
@@ -52,6 +52,73 @@ IF(MSVC OR MINGW)
ENDIF(CMAKE_CL_64)
ENDIF(MSVC OR MINGW)
# include dirs are universal
SET(NATS_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/nats")
#Try to find protobuf automatically
FIND_PACKAGE(Protobuf QUIET)
#IF(NOT PROTOBUF_FOUND)
SET(Protobuf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/protobuf" CACHE PATH "Root protobuf directory" FORCE)
SET(PROTOBUF_FOUND TRUE CACHE BOOL "" FORCE)
IF(MSVC)
IF(CMAKE_CL_64)
SET(Protobuf_INCLUDE_DIR "${Protobuf_DIR}/windows/x64/include" CACHE PATH "Include dir" FORCE)
SET(Protobuf_SRC_ROOT_FOLDER "${Protobuf_DIR}/windows/x64/include" CACHE PATH "Include dir" FORCE)
SET(Protobuf_PROTOC_EXECUTABLE "${Protobuf_DIR}/windows/x64/bin/protoc.exe" CACHE PATH "Executable path" FORCE)
SET(Protobuf_LIBRARY_DEBUG "${Protobuf_DIR}/windows/x64/lib/libprotobufd.lib" CACHE PATH "Root protobuf directory" FORCE)
SET(Protobuf_LIBRARY_RELEASE "${Protobuf_DIR}/windows/x64/lib/libprotobufd.lib" CACHE PATH "Root protobuf directory" FORCE)
ELSE(CMAKE_CL_64)
SET(Protobuf_INCLUDE_DIR "${Protobuf_DIR}/windows/x86/include" CACHE PATH "Include dir" FORCE)
SET(Protobuf_SRC_ROOT_FOLDER "${Protobuf_DIR}/windows/x86/include" CACHE PATH "Include dir" FORCE)
SET(Protobuf_PROTOC_EXECUTABLE "${Protobuf_DIR}/windows/x86/bin/protoc.exe" CACHE PATH "Executable path" FORCE)
SET(Protobuf_LIBRARY_DEBUG "${Protobuf_DIR}/windows/x86/lib/libprotobufd.lib" CACHE PATH "Root protobuf directory" FORCE)
SET(Protobuf_LIBRARY_RELEASE "${Protobuf_DIR}/windows/x86/lib/libprotobufd.lib" CACHE PATH "Root protobuf directory" FORCE)
ENDIF(CMAKE_CL_64)
ELSE(MSVC)
IF(CMAKE_CL_64)
SET(Protobuf_INCLUDE_DIR "${Protobuf_DIR}/linux/x86/include" CACHE PATH "Include dir" FORCE)
SET(Protobuf_SRC_ROOT_FOLDER "${Protobuf_DIR}/linux/x86/include" CACHE PATH "Include dir" FORCE)
SET(Protobuf_PROTOC_EXECUTABLE "${Protobuf_DIR}/linux/x86/bin/protoc" CACHE PATH "Executable path" FORCE)
SET(Protobuf_LIBRARY_DEBUG "${Protobuf_DIR}/linux/x86/lib/libprotobuf.so.16" CACHE PATH "Root protobuf directory" FORCE)
SET(Protobuf_LIBRARY_RELEASE "${Protobuf_DIR}/linux/x86/lib/libprotobuf.so.16" CACHE PATH "Root protobuf directory" FORCE)
ELSE(CMAKE_CL_64)
SET(Protobuf_INCLUDE_DIR "${Protobuf_DIR}/linux/x64/include" CACHE PATH "Include dir" FORCE)
SET(Protobuf_SRC_ROOT_FOLDER "${Protobuf_DIR}/linux/x64/include" CACHE PATH "Include dir" FORCE)
SET(Protobuf_PROTOC_EXECUTABLE "${Protobuf_DIR}/linux/x64/bin/protoc" CACHE PATH "Executable path" FORCE)
SET(Protobuf_LIBRARY_DEBUG "${Protobuf_DIR}/linux/x64/lib/libprotobuf.so.16" CACHE PATH "Root protobuf directory" FORCE)
SET(Protobuf_LIBRARY_RELEASE "${Protobuf_DIR}/linux/x64/lib/libprotobuf.so.16" CACHE PATH "Root protobuf directory" FORCE)
ENDIF(CMAKE_CL_64)
ENDIF()
IF(NOT Protobuf_LIBRARY_DEBUG)
MESSAGE(ERROR "Protobuf library was not found in ${Protobuf_LIBRARY_DEBUG}. Please download the depenencies and extract them as noted.")
ENDIF()
FILE(COPY ${Protobuf_LIBRARY_DEBUG} DESTINATION ${CMAKE_HOME_DIRECTORY}/bin)
#ENDIF()
INCLUDE_DIRECTORIES(SYSTEM "${Protobuf_INCLUDE_DIR}")
IF(MSVC)
IF(CMAKE_CL_64)
SET(NATS_INCLUDE_DIR "${NATS_ROOT}/windows/x64/include")
SET(NATS_LIBRARY_DEBUG "${NATS_ROOT}/windows/x64/lib/nats.lib")
ELSE(CMAKE_CL_64)
SET(NATS_INCLUDE_DIR "${NATS_ROOT}/windows/x86/include")
SET(NATS_LIBRARY_DEBUG "${NATS_ROOT}/windows/x86/lib/nats.lib")
ENDIF(CMAKE_CL_64)
ELSE(MSVC)
IF(CMAKE_CL_64)
SET(NATS_INCLUDE_DIR "${NATS_ROOT}/linux/x86/include")
SET(NATS_LIBRARY_DEBUG "${NATS_ROOT}/linux/x86/lib/libnats.so")
ELSE(CMAKE_CL_64)
SET(NATS_INCLUDE_DIR "${NATS_ROOT}/linux/x64/include")
SET(NATS_LIBRARY_DEBUG "${NATS_ROOT}/linux/x64/lib/libnats.so")
ENDIF(CMAKE_CL_64)
ENDIF()
IF(${NATS_LIBRARY_DEBUG})
MESSAGE(ERROR " NATS library was not found in ${NATS_LIBRARY_DEBUG}/libnats.so. Please download the depenencies and extract them as noted.")
ENDIF()
FILE(COPY ${NATS_LIBRARY_DEBUG} DESTINATION ${CMAKE_HOME_DIRECTORY}/bin)
IF(MSVC)
#Set our default locations for zlib/mysql based on x86/x64
IF(CMAKE_CL_64)
@@ -73,6 +140,7 @@ IF(MSVC)
SET(LUA_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/luaj_x86")
SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include")
SET(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/openssl_x86")
SET(NATS_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/nats_x86")
IF(MSVC_VERSION GREATER 1800)
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/Win32/Release/v140/dynamic")
ELSEIF(MSVC_VERSION EQUAL 1800)
@@ -131,6 +199,8 @@ IF(MSVC)
ADD_DEFINITIONS(-DNOMINMAX)
ELSE(MSVC)
#Normally set by perl but we don't use the perl flags anymore so we set it.
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
ENDIF(MSVC)
@@ -309,7 +379,7 @@ IF(EQEMU_BUILD_PERL)
INCLUDE_DIRECTORIES(SYSTEM "${PERL_INCLUDE_PATH}")
ENDIF(EQEMU_BUILD_PERL)
SET(SERVER_LIBS common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY} libuv fmt)
SET(SERVER_LIBS common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY} libuv fmt ${NATS_LIBRARY_DEBUG} ${PROTOBUF_LIBRARY_DEBUG})
FIND_PACKAGE(Sodium REQUIRED)
IF(SODIUM_FOUND)
@@ -352,12 +422,15 @@ ENDIF(EQEMU_BUILD_LUA)
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_INCLUDE_DIRS}")
INCLUDE_DIRECTORIES(SYSTEM "${MySQL_INCLUDE_DIR}")
INCLUDE_DIRECTORIES(SYSTEM "${NATS_INCLUDE_DIR}")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/common/glm")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/cereal")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/libuv/include" )
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/libuv/src")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/format")
IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC)
ADD_SUBDIRECTORY(common)
ADD_SUBDIRECTORY(libs)
+386
View File
@@ -0,0 +1,386 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
FindPackageHandleStandardArgs
-----------------------------
This module provides a function intended to be used in :ref:`Find Modules`
implementing :command:`find_package(<PackageName>)` calls. It handles the
``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``.
It also sets the ``<PackageName>_FOUND`` variable. The package is
considered found if all variables listed contain valid results, e.g.
valid filepaths.
.. command:: find_package_handle_standard_args
There are two signatures::
find_package_handle_standard_args(<PackageName>
(DEFAULT_MSG|<custom-failure-message>)
<required-var>...
)
find_package_handle_standard_args(<PackageName>
[FOUND_VAR <result-var>]
[REQUIRED_VARS <required-var>...]
[VERSION_VAR <version-var>]
[HANDLE_COMPONENTS]
[CONFIG_MODE]
[FAIL_MESSAGE <custom-failure-message>]
)
The ``<PackageName>_FOUND`` variable will be set to ``TRUE`` if all
the variables ``<required-var>...`` are valid and any optional
constraints are satisfied, and ``FALSE`` otherwise. A success or
failure message may be displayed based on the results and on
whether the ``REQUIRED`` and/or ``QUIET`` option was given to
the :command:`find_package` call.
The options are:
``(DEFAULT_MSG|<custom-failure-message>)``
In the simple signature this specifies the failure message.
Use ``DEFAULT_MSG`` to ask for a default message to be computed
(recommended). Not valid in the full signature.
``FOUND_VAR <result-var>``
Obsolete. Specifies either ``<PackageName>_FOUND`` or
``<PACKAGENAME>_FOUND`` as the result variable. This exists only
for compatibility with older versions of CMake and is now ignored.
Result variables of both names are always set for compatibility.
``REQUIRED_VARS <required-var>...``
Specify the variables which are required for this package.
These may be named in the generated failure message asking the
user to set the missing variable values. Therefore these should
typically be cache entries such as ``FOO_LIBRARY`` and not output
variables like ``FOO_LIBRARIES``.
``VERSION_VAR <version-var>``
Specify the name of a variable that holds the version of the package
that has been found. This version will be checked against the
(potentially) specified required version given to the
:command:`find_package` call, including its ``EXACT`` option.
The default messages include information about the required
version and the version which has been actually found, both
if the version is ok or not.
``HANDLE_COMPONENTS``
Enable handling of package components. In this case, the command
will report which components have been found and which are missing,
and the ``<PackageName>_FOUND`` variable will be set to ``FALSE``
if any of the required components (i.e. not the ones listed after
the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are
missing.
``CONFIG_MODE``
Specify that the calling find module is a wrapper around a
call to ``find_package(<PackageName> NO_MODULE)``. This implies
a ``VERSION_VAR`` value of ``<PackageName>_VERSION``. The command
will automatically check whether the package configuration file
was found.
``FAIL_MESSAGE <custom-failure-message>``
Specify a custom failure message instead of using the default
generated message. Not recommended.
Example for the simple signature:
.. code-block:: cmake
find_package_handle_standard_args(LibXml2 DEFAULT_MSG
LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)
The ``LibXml2`` package is considered to be found if both
``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid.
Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found
and ``REQUIRED`` was used, it fails with a
:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was
used or not. If it is found, success will be reported, including
the content of the first ``<required-var>``. On repeated CMake runs,
the same message will not be printed again.
Example for the full signature:
.. code-block:: cmake
find_package_handle_standard_args(LibArchive
REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR
VERSION_VAR LibArchive_VERSION)
In this case, the ``LibArchive`` package is considered to be found if
both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid.
Also the version of ``LibArchive`` will be checked by using the version
contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given,
the default messages will be printed.
Another example for the full signature:
.. code-block:: cmake
find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
find_package_handle_standard_args(Automoc4 CONFIG_MODE)
In this case, a ``FindAutmoc4.cmake`` module wraps a call to
``find_package(Automoc4 NO_MODULE)`` and adds an additional search
directory for ``automoc4``. Then the call to
``find_package_handle_standard_args`` produces a proper success/failure
message.
#]=======================================================================]
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake)
# internal helper macro
macro(_FPHSA_FAILURE_MESSAGE _msg)
if (${_NAME}_FIND_REQUIRED)
message(FATAL_ERROR "${_msg}")
else ()
if (NOT ${_NAME}_FIND_QUIETLY)
message(STATUS "${_msg}")
endif ()
endif ()
endmacro()
# internal helper macro to generate the failure message when used in CONFIG_MODE:
macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
# <name>_CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found:
if(${_NAME}_CONFIG)
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})")
else()
# If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version.
# List them all in the error message:
if(${_NAME}_CONSIDERED_CONFIGS)
set(configsText "")
list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount)
math(EXPR configsCount "${configsCount} - 1")
foreach(currentConfigIndex RANGE ${configsCount})
list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename)
list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version)
string(APPEND configsText " ${filename} (version ${version})\n")
endforeach()
if (${_NAME}_NOT_FOUND_MESSAGE)
string(APPEND configsText " Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n")
endif()
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}")
else()
# Simple case: No Config-file was found at all:
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}")
endif()
endif()
endmacro()
function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
# Set up the arguments for `cmake_parse_arguments`.
set(options CONFIG_MODE HANDLE_COMPONENTS)
set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR)
set(multiValueArgs REQUIRED_VARS)
# Check whether we are in 'simple' or 'extended' mode:
set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} )
list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
if(${INDEX} EQUAL -1)
set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
set(FPHSA_REQUIRED_VARS ${ARGN})
set(FPHSA_VERSION_VAR)
else()
cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN})
if(FPHSA_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"")
endif()
if(NOT FPHSA_FAIL_MESSAGE)
set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG")
endif()
# In config-mode, we rely on the variable <package>_CONFIG, which is set by find_package()
# when it successfully found the config-file, including version checking:
if(FPHSA_CONFIG_MODE)
list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG)
list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS)
set(FPHSA_VERSION_VAR ${_NAME}_VERSION)
endif()
if(NOT FPHSA_REQUIRED_VARS)
message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
endif()
endif()
# now that we collected all arguments, process them
if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG")
set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
endif()
list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
string(TOUPPER ${_NAME} _NAME_UPPER)
string(TOLOWER ${_NAME} _NAME_LOWER)
if(FPHSA_FOUND_VAR)
if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$")
set(_FOUND_VAR ${FPHSA_FOUND_VAR})
else()
message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.")
endif()
else()
set(_FOUND_VAR ${_NAME_UPPER}_FOUND)
endif()
# collect all variables which were not found, so they can be printed, so the
# user knows better what went wrong (#6375)
set(MISSING_VARS "")
set(DETAILS "")
# check if all passed variables are valid
set(FPHSA_FOUND_${_NAME} TRUE)
foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS})
if(NOT ${_CURRENT_VAR})
set(FPHSA_FOUND_${_NAME} FALSE)
string(APPEND MISSING_VARS " ${_CURRENT_VAR}")
else()
string(APPEND DETAILS "[${${_CURRENT_VAR}}]")
endif()
endforeach()
if(FPHSA_FOUND_${_NAME})
set(${_NAME}_FOUND TRUE)
set(${_NAME_UPPER}_FOUND TRUE)
else()
set(${_NAME}_FOUND FALSE)
set(${_NAME_UPPER}_FOUND FALSE)
endif()
# component handling
unset(FOUND_COMPONENTS_MSG)
unset(MISSING_COMPONENTS_MSG)
if(FPHSA_HANDLE_COMPONENTS)
foreach(comp ${${_NAME}_FIND_COMPONENTS})
if(${_NAME}_${comp}_FOUND)
if(NOT DEFINED FOUND_COMPONENTS_MSG)
set(FOUND_COMPONENTS_MSG "found components: ")
endif()
string(APPEND FOUND_COMPONENTS_MSG " ${comp}")
else()
if(NOT DEFINED MISSING_COMPONENTS_MSG)
set(MISSING_COMPONENTS_MSG "missing components: ")
endif()
string(APPEND MISSING_COMPONENTS_MSG " ${comp}")
if(${_NAME}_FIND_REQUIRED_${comp})
set(${_NAME}_FOUND FALSE)
string(APPEND MISSING_VARS " ${comp}")
endif()
endif()
endforeach()
set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}")
string(APPEND DETAILS "[c${COMPONENT_MSG}]")
endif()
# version handling:
set(VERSION_MSG "")
set(VERSION_OK TRUE)
# check with DEFINED here as the requested or found version may be "0"
if (DEFINED ${_NAME}_FIND_VERSION)
if(DEFINED ${FPHSA_VERSION_VAR})
set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}})
if(${_NAME}_FIND_VERSION_EXACT) # exact version required
# count the dots in the version string
string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}")
# add one dot because there is one dot more than there are components
string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS)
if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT)
# Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT
# is at most 4 here. Therefore a simple lookup table is used.
if (${_NAME}_FIND_VERSION_COUNT EQUAL 1)
set(_VERSION_REGEX "[^.]*")
elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2)
set(_VERSION_REGEX "[^.]*\\.[^.]*")
elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3)
set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*")
else ()
set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*")
endif ()
string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}")
unset(_VERSION_REGEX)
if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD)
set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
set(VERSION_OK FALSE)
else ()
set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")")
endif ()
unset(_VERSION_HEAD)
else ()
if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION)
set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
set(VERSION_OK FALSE)
else ()
set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")")
endif ()
endif ()
unset(_VERSION_DOTS)
else() # minimum version specified:
if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION)
set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"")
set(VERSION_OK FALSE)
else ()
set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")")
endif ()
endif()
else()
# if the package was not found, but a version was given, add that to the output:
if(${_NAME}_FIND_VERSION_EXACT)
set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")")
else()
set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")")
endif()
endif()
else ()
# Check with DEFINED as the found version may be 0.
if(DEFINED ${FPHSA_VERSION_VAR})
set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")")
endif()
endif ()
if(VERSION_OK)
string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]")
else()
set(${_NAME}_FOUND FALSE)
endif()
# print the result:
if (${_NAME}_FOUND)
FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}")
else ()
if(FPHSA_CONFIG_MODE)
_FPHSA_HANDLE_FAILURE_CONFIG_MODE()
else()
if(NOT VERSION_OK)
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})")
else()
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}")
endif()
endif()
endif ()
set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
endfunction()
+47
View File
@@ -0,0 +1,47 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#.rst:
# FindPackageMessage
# ------------------
#
#
#
# FIND_PACKAGE_MESSAGE(<name> "message for user" "find result details")
#
# This macro is intended to be used in FindXXX.cmake modules files. It
# will print a message once for each unique find result. This is useful
# for telling the user where a package was found. The first argument
# specifies the name (XXX) of the package. The second argument
# specifies the message to display. The third argument lists details
# about the find result so that if they change the message will be
# displayed again. The macro also obeys the QUIET argument to the
# find_package command.
#
# Example:
#
# ::
#
# if(X11_FOUND)
# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}"
# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]")
# else()
# ...
# endif()
function(FIND_PACKAGE_MESSAGE pkg msg details)
# Avoid printing a message repeatedly for the same find result.
if(NOT ${pkg}_FIND_QUIETLY)
string(REPLACE "\n" "" details "${details}")
set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg})
if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}")
# The message has not yet been printed.
message(STATUS "${msg}")
# Save the find details in the cache to avoid printing the same
# message again.
set("${DETAILS_VAR}" "${details}"
CACHE INTERNAL "Details about finding ${pkg}")
endif()
endif()
endfunction()
+579
View File
@@ -0,0 +1,579 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#.rst:
# FindProtobuf
# ------------
#
# Locate and configure the Google Protocol Buffers library.
#
# The following variables can be set and are optional:
#
# ``Protobuf_SRC_ROOT_FOLDER``
# When compiling with MSVC, if this cache variable is set
# the protobuf-default VS project build locations
# (vsprojects/Debug and vsprojects/Release
# or vsprojects/x64/Debug and vsprojects/x64/Release)
# will be searched for libraries and binaries.
# ``Protobuf_IMPORT_DIRS``
# List of additional directories to be searched for
# imported .proto files.
# ``Protobuf_DEBUG``
# Show debug messages.
# ``Protobuf_USE_STATIC_LIBS``
# Set to ON to force the use of the static libraries.
# Default is OFF.
#
# Defines the following variables:
#
# ``Protobuf_FOUND``
# Found the Google Protocol Buffers library
# (libprotobuf & header files)
# ``Protobuf_VERSION``
# Version of package found.
# ``Protobuf_INCLUDE_DIRS``
# Include directories for Google Protocol Buffers
# ``Protobuf_LIBRARIES``
# The protobuf libraries
# ``Protobuf_PROTOC_LIBRARIES``
# The protoc libraries
# ``Protobuf_LITE_LIBRARIES``
# The protobuf-lite libraries
#
# The following :prop_tgt:`IMPORTED` targets are also defined:
#
# ``protobuf::libprotobuf``
# The protobuf library.
# ``protobuf::libprotobuf-lite``
# The protobuf lite library.
# ``protobuf::libprotoc``
# The protoc library.
# ``protobuf::protoc``
# The protoc compiler.
#
# The following cache variables are also available to set or use:
#
# ``Protobuf_LIBRARY``
# The protobuf library
# ``Protobuf_PROTOC_LIBRARY``
# The protoc library
# ``Protobuf_INCLUDE_DIR``
# The include directory for protocol buffers
# ``Protobuf_PROTOC_EXECUTABLE``
# The protoc compiler
# ``Protobuf_LIBRARY_DEBUG``
# The protobuf library (debug)
# ``Protobuf_PROTOC_LIBRARY_DEBUG``
# The protoc library (debug)
# ``Protobuf_LITE_LIBRARY``
# The protobuf lite library
# ``Protobuf_LITE_LIBRARY_DEBUG``
# The protobuf lite library (debug)
#
# Example:
#
# .. code-block:: cmake
#
# find_package(Protobuf REQUIRED)
# include_directories(${Protobuf_INCLUDE_DIRS})
# include_directories(${CMAKE_CURRENT_BINARY_DIR})
# protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS foo.proto)
# protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS EXPORT_MACRO DLL_EXPORT foo.proto)
# protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS DESCRIPTORS PROTO_DESCS foo.proto)
# protobuf_generate_python(PROTO_PY foo.proto)
# add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
# target_link_libraries(bar ${Protobuf_LIBRARIES})
#
# .. note::
# The ``protobuf_generate_cpp`` and ``protobuf_generate_python``
# functions and :command:`add_executable` or :command:`add_library`
# calls only work properly within the same directory.
#
# .. command:: protobuf_generate_cpp
#
# Add custom commands to process ``.proto`` files to C++::
#
# protobuf_generate_cpp (<SRCS> <HDRS>
# [DESCRIPTORS <DESC>] [EXPORT_MACRO <MACRO>] [<ARGN>...])
#
# ``SRCS``
# Variable to define with autogenerated source files
# ``HDRS``
# Variable to define with autogenerated header files
# ``DESCRIPTORS``
# Variable to define with autogenerated descriptor files, if requested.
# ``EXPORT_MACRO``
# is a macro which should expand to ``__declspec(dllexport)`` or
# ``__declspec(dllimport)`` depending on what is being compiled.
# ``ARGN``
# ``.proto`` files
#
# .. command:: protobuf_generate_python
#
# Add custom commands to process ``.proto`` files to Python::
#
# protobuf_generate_python (<PY> [<ARGN>...])
#
# ``PY``
# Variable to define with autogenerated Python files
# ``ARGN``
# ``.proto`` filess
function(PROTOBUF_GENERATE_CPP SRCS HDRS)
cmake_parse_arguments(protobuf "" "EXPORT_MACRO;DESCRIPTORS" "" ${ARGN})
set(PROTO_FILES "${protobuf_UNPARSED_ARGUMENTS}")
if(NOT PROTO_FILES)
message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
return()
endif()
if(protobuf_EXPORT_MACRO)
set(DLL_EXPORT_DECL "dllexport_decl=${protobuf_EXPORT_MACRO}:")
endif()
if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
# Create an include path for each file specified
foreach(FIL ${PROTO_FILES})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(ABS_PATH ${ABS_FIL} PATH)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
if(${_contains_already} EQUAL -1)
list(APPEND _protobuf_include_path -I ${ABS_PATH})
endif()
endforeach()
else()
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
endif()
if(DEFINED PROTOBUF_IMPORT_DIRS AND NOT DEFINED Protobuf_IMPORT_DIRS)
set(Protobuf_IMPORT_DIRS "${PROTOBUF_IMPORT_DIRS}")
endif()
if(DEFINED Protobuf_IMPORT_DIRS)
foreach(DIR ${Protobuf_IMPORT_DIRS})
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
if(${_contains_already} EQUAL -1)
list(APPEND _protobuf_include_path -I ${ABS_PATH})
endif()
endforeach()
endif()
set(${SRCS})
set(${HDRS})
if (protobuf_DESCRIPTORS)
set(${protobuf_DESCRIPTORS})
endif()
foreach(FIL ${PROTO_FILES})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(FIL_WE ${FIL} NAME_WE)
if(NOT PROTOBUF_GENERATE_CPP_APPEND_PATH)
get_filename_component(FIL_DIR ${FIL} DIRECTORY)
if(FIL_DIR)
set(FIL_WE "${FIL_DIR}/${FIL_WE}")
endif()
endif()
set(_protobuf_protoc_src "${CMAKE_CURRENT_SOURCE_DIR}/${FIL_WE}.pb.cc")
set(_protobuf_protoc_hdr "${CMAKE_CURRENT_SOURCE_DIR}/${FIL_WE}.pb.h")
list(APPEND ${SRCS} "${_protobuf_protoc_src}")
list(APPEND ${HDRS} "${_protobuf_protoc_hdr}")
if(protobuf_DESCRIPTORS)
set(_protobuf_protoc_desc "${CMAKE_CURRENT_SOURCE_DIR}/${FIL_WE}.desc")
set(_protobuf_protoc_flags "--descriptor_set_out=${_protobuf_protoc_desc}")
list(APPEND ${protobuf_DESCRIPTORS} "${_protobuf_protoc_desc}")
else()
set(_protobuf_protoc_desc "")
set(_protobuf_protoc_flags "")
endif()
add_custom_command(
OUTPUT "${_protobuf_protoc_src}"
"${_protobuf_protoc_hdr}"
${_protobuf_protoc_desc}
COMMAND protobuf::protoc
"--cpp_out=${DLL_EXPORT_DECL}${CMAKE_CURRENT_SOURCE_DIR}"
${_protobuf_protoc_flags}
${_protobuf_include_path} ${ABS_FIL}
DEPENDS ${ABS_FIL} protobuf::protoc
COMMENT "Running C++ protocol buffer compiler on ${FIL}"
VERBATIM )
endforeach()
set(${SRCS} "${${SRCS}}" PARENT_SCOPE)
set(${HDRS} "${${HDRS}}" PARENT_SCOPE)
if(protobuf_DESCRIPTORS)
set(${protobuf_DESCRIPTORS} "${${protobuf_DESCRIPTORS}}" PARENT_SCOPE)
endif()
endfunction()
function(PROTOBUF_GENERATE_PYTHON SRCS)
if(NOT ARGN)
message(SEND_ERROR "Error: PROTOBUF_GENERATE_PYTHON() called without any proto files")
return()
endif()
if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
# Create an include path for each file specified
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(ABS_PATH ${ABS_FIL} PATH)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
if(${_contains_already} EQUAL -1)
list(APPEND _protobuf_include_path -I ${ABS_PATH})
endif()
endforeach()
else()
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
endif()
if(DEFINED PROTOBUF_IMPORT_DIRS AND NOT DEFINED Protobuf_IMPORT_DIRS)
set(Protobuf_IMPORT_DIRS "${PROTOBUF_IMPORT_DIRS}")
endif()
if(DEFINED Protobuf_IMPORT_DIRS)
foreach(DIR ${Protobuf_IMPORT_DIRS})
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
if(${_contains_already} EQUAL -1)
list(APPEND _protobuf_include_path -I ${ABS_PATH})
endif()
endforeach()
endif()
set(${SRCS})
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(FIL_WE ${FIL} NAME_WE)
if(NOT PROTOBUF_GENERATE_CPP_APPEND_PATH)
get_filename_component(FIL_DIR ${FIL} DIRECTORY)
if(FIL_DIR)
set(FIL_WE "${FIL_DIR}/${FIL_WE}")
endif()
endif()
list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py")
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py"
COMMAND protobuf::protoc --python_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL}
DEPENDS ${ABS_FIL} protobuf::protoc
COMMENT "Running Python protocol buffer compiler on ${FIL}"
VERBATIM )
endforeach()
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
endfunction()
if(Protobuf_DEBUG)
# Output some of their choices
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"Protobuf_USE_STATIC_LIBS = ${Protobuf_USE_STATIC_LIBS}")
endif()
# Backwards compatibility
# Define camel case versions of input variables
foreach(UPPER
PROTOBUF_SRC_ROOT_FOLDER
PROTOBUF_IMPORT_DIRS
PROTOBUF_DEBUG
PROTOBUF_LIBRARY
PROTOBUF_PROTOC_LIBRARY
PROTOBUF_INCLUDE_DIR
PROTOBUF_PROTOC_EXECUTABLE
PROTOBUF_LIBRARY_DEBUG
PROTOBUF_PROTOC_LIBRARY_DEBUG
PROTOBUF_LITE_LIBRARY
PROTOBUF_LITE_LIBRARY_DEBUG
)
if (DEFINED ${UPPER})
string(REPLACE "PROTOBUF_" "Protobuf_" Camel ${UPPER})
if (NOT DEFINED ${Camel})
set(${Camel} ${${UPPER}})
endif()
endif()
endforeach()
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_PROTOBUF_ARCH_DIR x64/)
endif()
# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
if( Protobuf_USE_STATIC_LIBS )
set( _protobuf_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
if(WIN32)
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
else()
set(CMAKE_FIND_LIBRARY_SUFFIXES .a )
endif()
endif()
include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
# Internal function: search for normal library as well as a debug one
# if the debug one is specified also include debug/optimized keywords
# in *_LIBRARIES variable
function(_protobuf_find_libraries name filename)
if(${name}_LIBRARIES)
# Use result recorded by a previous call.
return()
elseif(${name}_LIBRARY)
# Honor cache entry used by CMake 3.5 and lower.
set(${name}_LIBRARIES "${${name}_LIBRARY}" PARENT_SCOPE)
else()
find_library(${name}_LIBRARY_RELEASE
NAMES ${filename}
PATHS ${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Release)
mark_as_advanced(${name}_LIBRARY_RELEASE)
find_library(${name}_LIBRARY_DEBUG
NAMES ${filename}d ${filename}
PATHS ${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Debug)
mark_as_advanced(${name}_LIBRARY_DEBUG)
select_library_configurations(${name})
set(${name}_LIBRARY "${${name}_LIBRARY}" PARENT_SCOPE)
set(${name}_LIBRARIES "${${name}_LIBRARIES}" PARENT_SCOPE)
endif()
endfunction()
# Internal function: find threads library
function(_protobuf_find_threads)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads)
if(Threads_FOUND)
list(APPEND Protobuf_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
set(Protobuf_LIBRARIES "${Protobuf_LIBRARIES}" PARENT_SCOPE)
endif()
endfunction()
#
# Main.
#
# By default have PROTOBUF_GENERATE_CPP macro pass -I to protoc
# for each directory where a proto file is referenced.
if(NOT DEFINED PROTOBUF_GENERATE_CPP_APPEND_PATH)
set(PROTOBUF_GENERATE_CPP_APPEND_PATH TRUE)
endif()
# Google's provided vcproj files generate libraries with a "lib"
# prefix on Windows
if(MSVC)
set(Protobuf_ORIG_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}")
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
find_path(Protobuf_SRC_ROOT_FOLDER protobuf.pc.in)
endif()
# The Protobuf library
_protobuf_find_libraries(Protobuf protobuf)
#DOC "The Google Protocol Buffers RELEASE Library"
_protobuf_find_libraries(Protobuf_LITE protobuf-lite)
# The Protobuf Protoc Library
_protobuf_find_libraries(Protobuf_PROTOC protoc)
# Restore original find library prefixes
if(MSVC)
set(CMAKE_FIND_LIBRARY_PREFIXES "${Protobuf_ORIG_FIND_LIBRARY_PREFIXES}")
endif()
if(UNIX)
_protobuf_find_threads()
endif()
# Find the include directory
find_path(Protobuf_INCLUDE_DIR
google/protobuf/service.h
PATHS ${Protobuf_SRC_ROOT_FOLDER}/src
)
mark_as_advanced(Protobuf_INCLUDE_DIR)
# Find the protoc Executable
find_program(Protobuf_PROTOC_EXECUTABLE
NAMES protoc
DOC "The Google Protocol Buffers Compiler"
PATHS /usr/bin
${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Release
${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Debug
)
mark_as_advanced(Protobuf_PROTOC_EXECUTABLE)
if(Protobuf_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"requested version of Google Protobuf is ${Protobuf_FIND_VERSION}")
endif()
if(Protobuf_INCLUDE_DIR)
set(_PROTOBUF_COMMON_HEADER ${Protobuf_INCLUDE_DIR}/google/protobuf/stubs/common.h)
if(Protobuf_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"location of common.h: ${_PROTOBUF_COMMON_HEADER}")
endif()
set(Protobuf_VERSION "")
set(Protobuf_LIB_VERSION "")
file(STRINGS ${_PROTOBUF_COMMON_HEADER} _PROTOBUF_COMMON_H_CONTENTS REGEX "#define[ \t]+GOOGLE_PROTOBUF_VERSION[ \t]+")
if(_PROTOBUF_COMMON_H_CONTENTS MATCHES "#define[ \t]+GOOGLE_PROTOBUF_VERSION[ \t]+([0-9]+)")
set(Protobuf_LIB_VERSION "${CMAKE_MATCH_1}")
endif()
unset(_PROTOBUF_COMMON_H_CONTENTS)
math(EXPR _PROTOBUF_MAJOR_VERSION "${Protobuf_LIB_VERSION} / 1000000")
math(EXPR _PROTOBUF_MINOR_VERSION "${Protobuf_LIB_VERSION} / 1000 % 1000")
math(EXPR _PROTOBUF_SUBMINOR_VERSION "${Protobuf_LIB_VERSION} % 1000")
set(Protobuf_VERSION "${_PROTOBUF_MAJOR_VERSION}.${_PROTOBUF_MINOR_VERSION}.${_PROTOBUF_SUBMINOR_VERSION}")
if(Protobuf_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"${_PROTOBUF_COMMON_HEADER} reveals protobuf ${Protobuf_VERSION}")
endif()
# Check Protobuf compiler version to be aligned with libraries version
execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} --version
OUTPUT_VARIABLE _PROTOBUF_PROTOC_EXECUTABLE_VERSION)
if("${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}" MATCHES "libprotoc ([0-9.]+)")
set(_PROTOBUF_PROTOC_EXECUTABLE_VERSION "${CMAKE_MATCH_1}")
endif()
if(Protobuf_DEBUG)
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
"${Protobuf_PROTOC_EXECUTABLE} reveals version ${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}")
endif()
if(NOT "${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}" VERSION_EQUAL "${Protobuf_VERSION}")
message(WARNING "Protobuf compiler version ${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}"
" doesn't match library version ${Protobuf_VERSION}")
endif()
if(Protobuf_LIBRARY)
if(NOT TARGET protobuf::libprotobuf)
add_library(protobuf::libprotobuf UNKNOWN IMPORTED)
set_target_properties(protobuf::libprotobuf PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Protobuf_INCLUDE_DIR}")
if(EXISTS "${Protobuf_LIBRARY}")
set_target_properties(protobuf::libprotobuf PROPERTIES
IMPORTED_LOCATION "${Protobuf_LIBRARY}")
endif()
if(EXISTS "${Protobuf_LIBRARY_RELEASE}")
set_property(TARGET protobuf::libprotobuf APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(protobuf::libprotobuf PROPERTIES
IMPORTED_LOCATION_RELEASE "${Protobuf_LIBRARY_RELEASE}")
endif()
if(EXISTS "${Protobuf_LIBRARY_DEBUG}")
set_property(TARGET protobuf::libprotobuf APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(protobuf::libprotobuf PROPERTIES
IMPORTED_LOCATION_DEBUG "${Protobuf_LIBRARY_DEBUG}")
endif()
endif()
endif()
if(Protobuf_LITE_LIBRARY)
if(NOT TARGET protobuf::libprotobuf-lite)
add_library(protobuf::libprotobuf-lite UNKNOWN IMPORTED)
set_target_properties(protobuf::libprotobuf-lite PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Protobuf_INCLUDE_DIR}")
if(EXISTS "${Protobuf_LITE_LIBRARY}")
set_target_properties(protobuf::libprotobuf-lite PROPERTIES
IMPORTED_LOCATION "${Protobuf_LITE_LIBRARY}")
endif()
if(EXISTS "${Protobuf_LITE_LIBRARY_RELEASE}")
set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(protobuf::libprotobuf-lite PROPERTIES
IMPORTED_LOCATION_RELEASE "${Protobuf_LITE_LIBRARY_RELEASE}")
endif()
if(EXISTS "${Protobuf_LITE_LIBRARY_DEBUG}")
set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(protobuf::libprotobuf-lite PROPERTIES
IMPORTED_LOCATION_DEBUG "${Protobuf_LITE_LIBRARY_DEBUG}")
endif()
endif()
endif()
if(Protobuf_PROTOC_LIBRARY)
if(NOT TARGET protobuf::libprotoc)
add_library(protobuf::libprotoc UNKNOWN IMPORTED)
set_target_properties(protobuf::libprotoc PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Protobuf_INCLUDE_DIR}")
if(EXISTS "${Protobuf_PROTOC_LIBRARY}")
set_target_properties(protobuf::libprotoc PROPERTIES
IMPORTED_LOCATION "${Protobuf_PROTOC_LIBRARY}")
endif()
if(EXISTS "${Protobuf_PROTOC_LIBRARY_RELEASE}")
set_property(TARGET protobuf::libprotoc APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(protobuf::libprotoc PROPERTIES
IMPORTED_LOCATION_RELEASE "${Protobuf_PROTOC_LIBRARY_RELEASE}")
endif()
if(EXISTS "${Protobuf_PROTOC_LIBRARY_DEBUG}")
set_property(TARGET protobuf::libprotoc APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(protobuf::libprotoc PROPERTIES
IMPORTED_LOCATION_DEBUG "${Protobuf_PROTOC_LIBRARY_DEBUG}")
endif()
endif()
endif()
if(Protobuf_PROTOC_EXECUTABLE)
if(NOT TARGET protobuf::protoc)
add_executable(protobuf::protoc IMPORTED)
if(EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
set_target_properties(protobuf::protoc PROPERTIES
IMPORTED_LOCATION "${Protobuf_PROTOC_EXECUTABLE}")
endif()
endif()
endif()
endif()
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Protobuf
REQUIRED_VARS Protobuf_LIBRARIES Protobuf_INCLUDE_DIR
VERSION_VAR Protobuf_VERSION
)
if(Protobuf_FOUND)
set(Protobuf_INCLUDE_DIRS ${Protobuf_INCLUDE_DIR})
endif()
# Restore the original find library ordering
if( Protobuf_USE_STATIC_LIBS )
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_protobuf_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
endif()
# Backwards compatibility
# Define upper case versions of output variables
foreach(Camel
Protobuf_SRC_ROOT_FOLDER
Protobuf_IMPORT_DIRS
Protobuf_DEBUG
Protobuf_INCLUDE_DIRS
Protobuf_LIBRARIES
Protobuf_PROTOC_LIBRARIES
Protobuf_LITE_LIBRARIES
Protobuf_LIBRARY
Protobuf_PROTOC_LIBRARY
Protobuf_INCLUDE_DIR
Protobuf_PROTOC_EXECUTABLE
Protobuf_LIBRARY_DEBUG
Protobuf_PROTOC_LIBRARY_DEBUG
Protobuf_LITE_LIBRARY
Protobuf_LITE_LIBRARY_DEBUG
)
string(TOUPPER ${Camel} UPPER)
set(${UPPER} ${${Camel}})
endforeach()
+71
View File
@@ -0,0 +1,71 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#.rst:
# SelectLibraryConfigurations
# ---------------------------
#
#
#
# select_library_configurations( basename )
#
# This macro takes a library base name as an argument, and will choose
# good values for basename_LIBRARY, basename_LIBRARIES,
# basename_LIBRARY_DEBUG, and basename_LIBRARY_RELEASE depending on what
# has been found and set. If only basename_LIBRARY_RELEASE is defined,
# basename_LIBRARY will be set to the release value, and
# basename_LIBRARY_DEBUG will be set to basename_LIBRARY_DEBUG-NOTFOUND.
# If only basename_LIBRARY_DEBUG is defined, then basename_LIBRARY will
# take the debug value, and basename_LIBRARY_RELEASE will be set to
# basename_LIBRARY_RELEASE-NOTFOUND.
#
# If the generator supports configuration types, then basename_LIBRARY
# and basename_LIBRARIES will be set with debug and optimized flags
# specifying the library to be used for the given configuration. If no
# build type has been set or the generator in use does not support
# configuration types, then basename_LIBRARY and basename_LIBRARIES will
# take only the release value, or the debug value if the release one is
# not set.
# This macro was adapted from the FindQt4 CMake module and is maintained by Will
# Dicharry <wdicharry@stellarscience.com>.
macro( select_library_configurations basename )
if(NOT ${basename}_LIBRARY_RELEASE)
set(${basename}_LIBRARY_RELEASE "${basename}_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to a library.")
endif()
if(NOT ${basename}_LIBRARY_DEBUG)
set(${basename}_LIBRARY_DEBUG "${basename}_LIBRARY_DEBUG-NOTFOUND" CACHE FILEPATH "Path to a library.")
endif()
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND
NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE AND
( _isMultiConfig OR CMAKE_BUILD_TYPE ) )
# if the generator is multi-config or if CMAKE_BUILD_TYPE is set for
# single-config generators, set optimized and debug libraries
set( ${basename}_LIBRARY "" )
foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE )
list( APPEND ${basename}_LIBRARY optimized "${_libname}" )
endforeach()
foreach( _libname IN LISTS ${basename}_LIBRARY_DEBUG )
list( APPEND ${basename}_LIBRARY debug "${_libname}" )
endforeach()
elseif( ${basename}_LIBRARY_RELEASE )
set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} )
elseif( ${basename}_LIBRARY_DEBUG )
set( ${basename}_LIBRARY ${${basename}_LIBRARY_DEBUG} )
else()
set( ${basename}_LIBRARY "${basename}_LIBRARY-NOTFOUND")
endif()
set( ${basename}_LIBRARIES "${${basename}_LIBRARY}" )
if( ${basename}_LIBRARY )
set( ${basename}_FOUND TRUE )
endif()
mark_as_advanced( ${basename}_LIBRARY_RELEASE
${basename}_LIBRARY_DEBUG
)
endmacro()
+7 -2
View File
@@ -1,4 +1,7 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(PROTOBUF_GENERATE_CPP_APPEND_PATH "../../")
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HEADERS message.proto)
SET(common_sources
base_packet.cpp
@@ -39,9 +42,10 @@ SET(common_sources
item_instance.cpp
json_config.cpp
light_source.cpp
md5.cpp
md5.cpp
memory_buffer.cpp
memory_mapped_file.cpp
message.pb.cc
misc.cpp
misc_functions.cpp
mutex.cpp
@@ -97,7 +101,7 @@ SET(common_sources
patches/titanium.cpp
patches/titanium_limits.cpp
patches/uf.cpp
patches/uf_limits.cpp
patches/uf_limits.cpp
StackWalker/StackWalker.cpp
tinyxml/tinystr.cpp
tinyxml/tinyxml.cpp
@@ -167,6 +171,7 @@ SET(common_headers
md5.h
memory_buffer.h
memory_mapped_file.h
message.pb.h
misc.h
misc_functions.h
mutex.h
+4
View File
@@ -81,6 +81,10 @@ class EQEmuConfig
std::string QSDatabaseDB;
uint16 QSDatabasePort;
// From <nats/>
std::string NATSHost;
uint16 NATSPort;
// From <files/>
std::string SpellsFile;
std::string OpCodesFile;
+2
View File
@@ -104,6 +104,7 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
log_settings[Logs::MySQLError].log_to_console = Logs::General;
log_settings[Logs::Login_Server].log_to_console = Logs::General;
log_settings[Logs::Headless_Client].log_to_console = Logs::General;
log_settings[Logs::NATS].log_to_console = Logs::General;
/* Set Category enabled status on defaults */
log_settings[Logs::World_Server].is_category_enabled = 1;
@@ -113,6 +114,7 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
log_settings[Logs::Crash].is_category_enabled = 1;
log_settings[Logs::MySQLError].is_category_enabled = 1;
log_settings[Logs::Login_Server].is_category_enabled = 1;
log_settings[Logs::NATS].is_category_enabled = 1;
/* Declare process file names for log writing
If there is no process_file_name declared, no log file will be written, simply
+3 -1
View File
@@ -90,6 +90,7 @@ enum LogCategory {
FixZ,
Food,
Traps,
NATS,
MaxCategoryID /* Don't Remove this*/
};
@@ -144,7 +145,8 @@ static const char* LogCategoryName[LogCategory::MaxCategoryID] = {
"HP Update",
"FixZ",
"Food",
"Traps"
"Traps",
"NATS"
};
}
+1254
View File
File diff suppressed because it is too large Load Diff
+8
View File
@@ -0,0 +1,8 @@
# Protobuf
* [https://developers.google.com/protocol-buffers/](Learn more about protobuf)
* Version is 3.5.1 (latest). In order to modify *.pb.cpp files, you need to have the [https://github.com/google/protobuf/releases](protoc binary).
* If you add any new .proto files, you need to include them into the CMakeList.txt entry of the respective dir, likely common/CMakeList.txt.
* By default, the generated cpp files are placed in the common/proto/* directory, while this is not best practice to have them versioned as they are auto generated files, it simplifies compiling source by not requiring protoc. (Perhaps later, we can look into adding this flow into cmake)
* Run build.bat or build.sh to build protobuf for different platforms.
* Look at each language subdirectory to learn more about building them
+8
View File
@@ -0,0 +1,8 @@
@echo off
mkdir go\eqproto python\proto java\eqproto csharp\proto
del /q ..\common\proto\*
del /q go\eqproto\*
del /q python\proto\*
del /q java\eqproto\*
del /q csharp\proto\*
..\dependencies\protobuf\bin\protoc --go_out=go/eqproto --python_out=python/proto --csharp_out=csharp/proto --java_out=java --proto_path=../common message.proto
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
set -e
echo "Cleaning up existing .pb files"
rm -rf ../common/proto/* go/eqproto/* csharp/proto/*.cs java/eqproto/*.java python/proto/*pb2*
protoc --go_out=go/eqproto --python_out=python/proto --csharp_out=csharp/proto --java_out=java -I ../common/ message.proto
+883
View File
@@ -0,0 +1,883 @@
syntax = "proto3";
package eqproto;
message ChannelMessage {
int32 chan_num = 1;
int32 language = 2;
string from = 3;
string to = 4;
string message = 5;
int32 guilddbid = 6;
string deliverto = 7;
int32 type = 8;
int32 minstatus = 9;
int32 fromadmin = 10;
bool noreply = 11;
bool is_emote = 12;
//0 not queued, 1 queued, 2 queue full, 3 offline
int32 queued = 13;
//You can specify a zone id if you want a message exclusively to one zone
int32 zone_id = 14;
}
message CommandMessage {
string author = 1;
string command = 2;
repeated string params = 3;
string result = 4;
bytes payload = 5;
}
//Daily Gain is a special system for tracking players progression in a daily snapshot.
message DailyGain {
int32 account_id = 1;
int32 character_id = 2;
int32 levels_gained = 3;
int32 experience_gained = 4;
int32 money_earned = 5;
string identity = 6;
}
//Entity is full of entity data.
message Entity {
int32 id = 1;
string name = 2;
int32 type = 3;
int32 hp = 4;
int32 level = 5;
Position position = 6;
int32 race = 7;
int32 class = 8;
}
message Entities {
repeated Entity entities = 1;
}
message Position {
float x = 1;
float y = 2;
float z = 3;
float h = 4;
}
message TextureProfile {
Texture Head = 1;
Texture Chest = 2;
Texture Arms = 3;
Texture Wrist = 4;
Texture Hands = 5;
Texture Legs = 6;
Texture Feet = 7;
Texture Primary = 8;
Texture Secondary = 9;
}
message Texture {
uint32 material = 1;
uint32 unknown1 = 2;
uint32 EliteModel = 3;
uint32 HerosForgeModel = 4;
uint32 Unknown2 = 5;
}
message TintProfile {
Tint Head = 1;
Tint Chest = 2;
Tint Arms = 3;
Tint Wrist = 4;
Tint Hands = 5;
Tint Legs = 6;
Tint Feet = 7;
Tint Primary = 8;
Tint Secondary = 9;
}
message Tint {
uint32 Blue = 1;
uint32 Green = 2;
uint32 Red = 3;
uint32 UseTint = 4; // if there's a tint, this is FF
uint32 Color = 5;
}
message Event {
OpCode op = 1;
bytes payload = 2;
}
//OP_Death
message DeathEvent {
uint32 spawn_id = 1;
uint32 killer_id = 2;
uint32 corpse_id = 3;
uint32 bind_zone_id = 4;
uint32 spell_id = 5;
uint32 attack_skill_id = 6;
uint32 damage = 7;
uint32 unknown028 = 8;
}
//OP_Damage
message DamageEvent {
uint32 target = 1;
uint32 source = 2;
uint32 type = 3; //slashing, etc. 231 (0xE7) for spells
uint32 spellid = 4;
uint32 damage = 5;
float force = 6;
float meleepush_xy = 7; // see above notes in Action_Struct
float meleepush_z = 8;
}
//OP_Assist OP_Camp
message EntityEvent {
uint32 entity_id = 1; //source of event trigger.
uint32 target_id = 2; //target or other/source/target entity
}
//OP_ChannelMessage
message ChannelMessageEvent {
string target_name = 1; // Tell recipient
string sender = 2; // The senders name (len might be wrong)
uint32 language = 3; // Language
uint32 chan_num = 4; // Channel
uint32 cm_unknown4 = 5; // ***Placeholder
uint32 skill_in_language = 6; // The players skill in this language? might be wrong
string message = 7; // Variable length message
}
//OP_WearChange
message WearChangeEvent {
uint32 spawn_id = 1;
uint32 material = 2;
uint32 unknown06 = 3;
uint32 elite_material = 4; // 1 for Drakkin Elite Material
uint32 hero_forge_model = 5; // New to VoA
uint32 unknown18 = 6; // New to RoF
Tint color = 7;
uint32 wear_slot_id = 8;
}
//OP_DeleteSpawn
message DeleteSpawnEvent {
uint32 spawn_id = 1; // Spawn ID to delete
uint32 decay = 2; // 0 = vanish immediately, 1 = 'Decay' sparklies for corpses.
}
//OP_MobHealth, OP_HPUpdate
message HPEvent {
uint32 spawn_id = 1;
uint32 cur_hp = 2;
uint32 max_hp = 3;
}
//OP_ClientUpdate
message PlayerPositionUpdateEvent {
uint32 spawn_id = 1;
int32 delta_heading = 2; // change in heading
int32 x_pos = 3; // x coord
int32 padding0002 = 4; // ***Placeholder
int32 y_pos = 5; // y coord
int32 animation = 6; // animation
int32 padding0006 = 7; // ***Placeholder
int32 z_pos = 8; // z coord
int32 delta_y = 9; // change in y
int32 delta_x = 10; // change in x
int32 heading = 11; // heading
int32 padding0014 = 12; // ***Placeholder
int32 delta_z = 13; // change in z
int32 padding0018 = 14; // ***Placeholder
}
//OP_Animation
message AnimationEvent {
uint32 spawnid = 1;
uint32 speed = 2;
uint32 action = 3;
}
//OP_ZoneEntry OP_NewSpawn
message SpawnEvent {
uint32 unknown0000= 1;
uint32 gm = 2; // 0=no, 1=gm
uint32 unknown0003 = 3;
uint32 aaitle = 4; // 0=none, 1=general, 2=archtype, 3=class
uint32 unknown0004 = 5;
uint32 anon = 6; // 0=normal, 1=anon, 2=roleplay
uint32 face = 7; // Face id for players
string name = 8; // Player's Name
uint32 deity = 9; // Player's Deity
uint32 unknown0073 = 10;
float size = 11; // Model size
uint32 unknown0079 = 12;
uint32 NPC = 13; // 0=player,1=npc,2=pc corpse,3=npc corpse,a
uint32 invis = 14; // Invis (0=not, 1=invis)
uint32 haircolor = 15; // Hair color
uint32 curHp = 16; // Current hp %%% wrong
uint32 max_hp = 17; // (name prolly wrong)takes on the value 100 for players, 100 or 110 for NPCs and 120 for PC corpses...
uint32 findable = 18; // 0=can't be found, 1=can be found
uint32 unknown0089 = 19;
int32 deltaHeading = 20; // change in heading
int32 x = 21; // x coord
int32 padding0054 = 22; // ***Placeholder
int32 y = 23; // y coord
int32 animation = 24; // animation
int32 padding0058 = 25; // ***Placeholder
int32 z = 26; // z coord
int32 deltaY = 27; // change in y
int32 deltaX = 28; // change in x
uint32 heading = 29; // heading
int32 padding0066 = 30; // ***Placeholder
int32 deltaZ = 31; // change in z
int32 padding0070 = 32; // ***Placeholder
uint32 eyecolor1 = 33; // Player's left eye color
uint32 unknown0115 = 34; // Was [24]
uint32 StandState = 35; // stand state for SoF+ 0x64 for normal animation
uint32 drakkin_heritage = 36; // Added for SoF
uint32 drakkin_tattoo = 37; // Added for SoF
uint32 drakkin_details = 38; // Added for SoF
uint32 showhelm = 39; // 0=no, 1=yes
uint32 unknown0140 = 40;
uint32 is_npc = 41; // 0=no, 1=yes
uint32 hairstyle = 42; // Hair style
uint32 beard = 43; // Beard style (not totally, sure but maybe!)
uint32 unknown0147 = 44;
uint32 level = 45; // Spawn Level
uint32 PlayerState = 46; // Controls animation stuff // None = 0, Open = 1, WeaponSheathed = 2, Aggressive = 4, ForcedAggressive = 8, InstrumentEquipped = 16, Stunned = 32, PrimaryWeaponEquipped = 64, SecondaryWeaponEquipped = 128
uint32 beardcolor = 47; // Beard color
string suffix = 48; // Player's suffix (of Veeshan, etc.)
uint32 petOwnerId = 49; // If this is a pet, the spawn id of owner
uint32 guildrank = 50; // 0=normal, 1=officer, 2=leader
uint32 unknown0194 = 51;
TextureProfile equipment = 52;
float runspeed = 53; // Speed when running
uint32 afk = 54; // 0=no, 1=afk
uint32 guildID = 55; // Current guild
string title = 56; // Title
uint32 unknown0274 = 57; // non-zero prefixes name with '!'
uint32 set_to_0xFF = 58; // ***Placeholder (all ff)
uint32 helm = 59; // Helm texture
uint32 race = 60; // Spawn race
uint32 unknown0288 = 61;
string lastName = 62; // Player's Lastname
float walkspeed = 63; // Speed when walking
uint32 unknown0328 = 64;
uint32 is_pet = 65; // 0=no, 1=yes
uint32 light = 66; // Spawn's lightsource %%% wrong
uint32 class_ = 67; // Player's class
uint32 eyecolor2 = 68; // Left eye color
uint32 flymode = 69;
uint32 gender = 70; // Gender (0=male, 1=female)
uint32 bodytype = 71; // Bodytype
uint32 unknown0336 = 72;
//union
uint32 equip_chest2 = 73; // Second place in packet for chest texture (usually 0xFF in live packets) // Not sure why there are 2 of them, but it effects chest texture!
uint32 mount_color = 74; // drogmor: 0=white, 1=black, 2=green, 3=red horse: 0=brown, 1=white, 2=black, 3=tan
//endunion
uint32 spawnId = 75; // Spawn Id
uint32 unknown0344 = 76;
uint32 IsMercenary = 77;
TintProfile equipment_tint = 78;
uint32 lfg = 79; // 0=off, 1=lfg on
bool DestructibleObject = 80; // Only used to flag as a destrible object
string DestructibleModel = 82; // Model of the Destructible Object - Required - Seen "DEST_TNT_G"
string DestructibleName2 = 83; // Secondary name - Not Required - Seen "a_tent"
string DestructibleString = 84; // Unknown - Not Required - Seen "ZoneActor_01186"
uint32 DestructibleAppearance = 85; // Damage Appearance
uint32 DestructibleUnk1 = 86;
uint32 DestructibleID1 = 87;
uint32 DestructibleID2 = 88;
uint32 DestructibleID3 = 89;
uint32 DestructibleID4 = 90;
uint32 DestructibleUnk2 = 91;
uint32 DestructibleUnk3 = 92;
uint32 DestructibleUnk4 = 93;
uint32 DestructibleUnk5 = 94;
uint32 DestructibleUnk6 = 95;
uint32 DestructibleUnk7 = 96;
uint32 DestructibleUnk8 = 97;
uint32 DestructibleUnk9 = 98;
bool targetable_with_hotkey = 99;
bool show_name= 100;
}
enum OpCode {
//option allow_alias = true;
OP_Unknown = 0;
OP_ExploreUnknown = 1;
OP_0x0193 = 2;
OP_0x0347 = 3;
OP_AAAction = 4;
OP_AAExpUpdate = 5;
OP_AcceptNewTask = 6;
OP_AckPacket = 7;
OP_Action = 8;
OP_Action2 = 9;
OP_AddNimbusEffect = 10;
OP_AdventureData = 11;
OP_AdventureDetails = 12;
OP_AdventureFinish = 13;
OP_AdventureInfo = 14;
OP_AdventureInfoRequest = 15;
OP_AdventureLeaderboardReply = 16;
OP_AdventureLeaderboardRequest = 17;
OP_AdventureMerchantPurchase = 18;
OP_AdventureMerchantRequest = 19;
OP_AdventureMerchantResponse = 20;
OP_AdventureMerchantSell = 21;
OP_AdventurePointsUpdate = 22;
OP_AdventureRequest = 23;
OP_AdventureStatsReply = 24;
OP_AdventureStatsRequest = 25;
OP_AdventureUpdate = 26;
OP_AggroMeterLockTarget = 27;
OP_AggroMeterTargetInfo = 28;
OP_AggroMeterUpdate = 29;
OP_AltCurrency = 30;
OP_AltCurrencyMerchantReply = 31;
OP_AltCurrencyMerchantRequest = 32;
OP_AltCurrencyPurchase = 33;
OP_AltCurrencyReclaim = 34;
OP_AltCurrencySell = 35;
OP_AltCurrencySellSelection = 36;
OP_Animation = 37; //supported
OP_AnnoyingZoneUnknown = 38;
OP_ApplyPoison = 39;
OP_ApproveName = 40;
OP_ApproveWorld = 41;
OP_ApproveZone = 42;
OP_Assist = 43; //supported
OP_AssistGroup = 44;
OP_AugmentInfo = 45;
OP_AugmentItem = 46;
OP_AutoAttack = 47;
OP_AutoAttack2 = 48;
OP_AutoFire = 49;
OP_Bandolier = 50;
OP_BankerChange = 51;
OP_Barter = 52;
OP_Bazaar = 53;
OP_BazaarInspect = 54;
OP_BazaarSearch = 55;
OP_BecomeCorpse = 56;
OP_BecomeTrader = 57;
OP_Begging = 58;
OP_BeginCast = 59;
OP_Bind_Wound = 60;
OP_BlockedBuffs = 61;
OP_BoardBoat = 62;
OP_Buff = 63;
OP_BuffCreate = 64;
OP_BuffRemoveRequest = 65;
OP_Bug = 66;
OP_CameraEffect = 67;
OP_Camp = 68; //supported
OP_CancelSneakHide = 69;
OP_CancelTask = 70;
OP_CancelTrade = 71;
OP_CastSpell = 72;
OP_ChangeSize = 73;
OP_ChannelMessage = 74;
OP_CharacterCreate = 75;
OP_CharacterCreateRequest = 76;
OP_CharInventory = 77;
OP_Charm = 78;
OP_ChatMessage = 79; //used by lua
OP_ClearAA = 80;
OP_ClearBlockedBuffs = 81;
OP_ClearLeadershipAbilities = 82;
OP_ClearNPCMarks = 83;
OP_ClearObject = 84;
OP_ClearSurname = 85;
OP_ClickDoor = 86;
OP_ClickObject = 87;
OP_ClickObjectAction = 88;
OP_ClientError = 89;
OP_ClientReady = 90;
OP_ClientTimeStamp = 91;
OP_ClientUpdate = 92; //supported
OP_CloseContainer = 93;
OP_CloseTributeMaster = 94;
OP_ColoredText = 95;
OP_CombatAbility = 96;
OP_Command = 97;
OP_CompletedTasks = 98;
OP_ConfirmDelete = 99;
OP_Consent = 100;
OP_ConsentDeny = 101;
OP_ConsentResponse = 102;
OP_Consider = 103;
OP_ConsiderCorpse = 104;
OP_Consume = 105;
OP_ControlBoat = 106;
OP_CorpseDrag = 107;
OP_CorpseDrop = 108;
OP_CrashDump = 109;
OP_CrystalCountUpdate = 110;
OP_CrystalCreate = 111;
OP_CrystalReclaim = 112;
OP_CustomTitles = 113;
OP_Damage = 114;
OP_Death = 115;
OP_DelegateAbility = 116;
OP_DeleteCharacter = 117;
OP_DeleteCharge = 118;
OP_DeleteItem = 119;
OP_DeletePetition = 120;
OP_DeleteSpawn = 121; //supported
OP_DeleteSpell = 122;
OP_DenyResponse = 123;
OP_Disarm = 124;
OP_DisarmTraps = 125;
OP_DisciplineTimer = 126;
OP_DisciplineUpdate = 127;
OP_DiscordMerchantInventory = 128;
OP_DoGroupLeadershipAbility = 129;
OP_DuelResponse = 130;
OP_DuelResponse2 = 131;
OP_DumpName = 132;
OP_Dye = 133;
OP_DynamicWall = 134;
OP_DzAddPlayer = 135;
OP_DzChooseZone = 136;
OP_DzCompass = 137;
OP_DzExpeditionEndsWarning = 138;
OP_DzExpeditionInfo = 139;
OP_DzExpeditionList = 140;
OP_DzJoinExpeditionConfirm = 141;
OP_DzJoinExpeditionReply = 142;
OP_DzLeaderStatus = 143;
OP_DzListTimers = 144;
OP_DzMakeLeader = 145;
OP_DzMemberList = 146;
OP_DzMemberStatus = 147;
OP_DzPlayerList = 148;
OP_DzQuit = 149;
OP_DzRemovePlayer = 150;
OP_DzSwapPlayer = 151;
OP_Emote = 152;
OP_EndLootRequest = 153;
OP_EnduranceUpdate = 154;
OP_EnterChat = 155;
OP_EnterWorld = 156;
OP_EnvDamage = 157;
OP_ExpansionInfo = 158;
OP_ExpUpdate = 159;
OP_FaceChange = 160;
OP_Feedback = 161;
OP_FeignDeath = 162;
OP_FellowshipUpdate = 163;
OP_FindPersonReply = 164;
OP_FindPersonRequest = 165;
OP_FinishTrade = 166;
OP_FinishWindow = 167;
OP_FinishWindow2 = 168;
OP_Fishing = 169;
OP_Fling = 170;
OP_FloatListThing = 171;
OP_Forage = 172;
OP_ForceFindPerson = 173;
OP_FormattedMessage = 174;
OP_FriendsWho = 175;
OP_GetGuildMOTD = 176;
OP_GetGuildMOTDReply = 177;
OP_GetGuildsList = 178;
OP_GiveMoney = 179;
OP_GMApproval = 180;
OP_GMBecomeNPC = 181;
OP_GMDelCorpse = 182;
OP_GMEmoteZone = 183;
OP_GMEndTraining = 184;
OP_GMEndTrainingResponse = 185;
OP_GMFind = 186;
OP_GMGoto = 187;
OP_GMHideMe = 188;
OP_GMKick = 189;
OP_GMKill = 190;
OP_GMLastName = 191;
OP_GMNameChange = 192;
OP_GMSearchCorpse = 193;
OP_GMServers = 194;
OP_GMSummon = 195;
OP_GMToggle = 196;
OP_GMTraining = 197;
OP_GMTrainSkill = 198;
OP_GMTrainSkillConfirm = 199;
OP_GMZoneRequest = 200;
OP_GMZoneRequest2 = 201;
OP_GroundSpawn = 202;
OP_GroupAcknowledge = 203;
OP_GroupCancelInvite = 204;
OP_GroupDelete = 205;
OP_GroupDisband = 206;
OP_GroupDisbandOther = 207;
OP_GroupDisbandYou = 208;
OP_GroupFollow = 209;
OP_GroupFollow2 = 210;
OP_GroupInvite = 211;
OP_GroupInvite2 = 212;
OP_GroupLeaderChange = 213;
OP_GroupLeadershipAAUpdate = 214;
OP_GroupMakeLeader = 215;
OP_GroupMentor = 216;
OP_GroupRoles = 217;
OP_GroupUpdate = 218;
OP_GroupUpdateB = 219;
OP_GroupUpdateLeaderAA = 220;
OP_GuildBank = 221;
OP_GuildBankItemList = 222;
OP_GuildCreate = 223;
OP_GuildDelete = 224;
OP_GuildDemote = 225;
OP_GuildInvite = 226;
OP_GuildInviteAccept = 227;
OP_GuildLeader = 228;
OP_GuildManageAdd = 229;
OP_GuildManageBanker = 230;
OP_GuildManageRemove = 231;
OP_GuildManageStatus = 232;
OP_GuildMemberLevelUpdate = 233;
OP_GuildMemberList = 234;
OP_GuildMemberUpdate = 235;
OP_GuildMOTD = 236;
OP_GuildPeace = 237;
OP_GuildPromote = 238;
OP_GuildPublicNote = 239;
OP_GuildRemove = 240;
OP_GuildsList = 241;
OP_GuildStatus = 242;
OP_GuildTributeInfo = 243;
OP_GuildUpdateURLAndChannel = 244;
OP_GuildWar = 245;
OP_Heartbeat = 246;
OP_Hide = 247;
OP_HideCorpse = 248;
OP_HPUpdate = 249; //supported
OP_Illusion = 250;
OP_IncreaseStats = 251;
OP_InitialHPUpdate = 252;
OP_InitialMobHealth = 253;
OP_InspectAnswer = 254;
OP_InspectBuffs = 255;
OP_InspectMessageUpdate = 256;
OP_InspectRequest = 257;
OP_InstillDoubt = 258;
OP_InterruptCast = 259;
OP_ItemLinkClick = 260;
OP_ItemLinkResponse = 261;
OP_ItemLinkText = 262;
OP_ItemName = 263;
OP_ItemPacket = 264;
OP_ItemPreview = 265;
OP_ItemRecastDelay = 266;
OP_ItemVerifyReply = 267;
OP_ItemVerifyRequest = 268;
OP_ItemViewUnknown = 269;
OP_Jump = 270;
OP_KeyRing = 271;
OP_KnowledgeBase = 272;
OP_LDoNButton = 273;
OP_LDoNDisarmTraps = 274;
OP_LDoNInspect = 275;
OP_LDoNOpen = 276;
OP_LDoNPickLock = 277;
OP_LDoNSenseTraps = 278;
OP_LeadershipExpToggle = 279;
OP_LeadershipExpUpdate = 280;
OP_LeaveAdventure = 281;
OP_LeaveBoat = 282;
OP_LevelAppearance = 283;
OP_LevelUpdate = 284;
OP_LFGAppearance = 285;
OP_LFGCommand = 286;
OP_LFGGetMatchesRequest = 287;
OP_LFGGetMatchesResponse = 288;
OP_LFGResponse = 289;
OP_LFGuild = 290;
OP_LFPCommand = 291;
OP_LFPGetMatchesRequest = 292;
OP_LFPGetMatchesResponse = 293;
OP_LinkedReuse = 294;
OP_LoadSpellSet = 295;
OP_LocInfo = 296;
OP_LockoutTimerInfo = 297;
OP_Login = 298;
OP_LoginAccepted = 299;
OP_LoginComplete = 300;
OP_LoginUnknown1 = 301;
OP_LoginUnknown2 = 302;
OP_Logout = 303;
OP_LogoutReply = 304;
OP_LogServer = 305;
OP_LootComplete = 306;
OP_LootItem = 307;
OP_LootRequest = 308;
OP_ManaChange = 309;
OP_ManaUpdate = 310;
OP_MarkNPC = 311;
OP_Marquee = 312;
OP_MemorizeSpell = 313;
OP_Mend = 314;
OP_MendHPUpdate = 315;
OP_MercenaryAssign = 316;
OP_MercenaryCommand = 317;
OP_MercenaryDataRequest = 318;
OP_MercenaryDataResponse = 319;
OP_MercenaryDataUpdate = 320;
OP_MercenaryDataUpdateRequest = 321;
OP_MercenaryDismiss = 322;
OP_MercenaryHire = 323;
OP_MercenarySuspendRequest = 324;
OP_MercenarySuspendResponse = 325;
OP_MercenaryTimer = 326;
OP_MercenaryTimerRequest = 327;
OP_MercenaryUnknown1 = 328;
OP_MercenaryUnsuspendResponse = 329;
OP_MobEnduranceUpdate = 330;
OP_MobHealth = 331; //supported
OP_MobManaUpdate = 332;
OP_MobRename = 333;
OP_MobUpdate = 334; // not used anymore, here for lecacy reasons eqextractor
OP_MoneyOnCorpse = 335;
OP_MoneyUpdate = 336;
OP_MOTD = 337;
OP_MoveCoin = 338;
OP_MoveDoor = 339;
OP_MoveItem = 340;
OP_MoveLogDisregard = 341;
OP_MoveLogRequest = 342;
OP_MultiLineMsg = 343;
OP_NewSpawn = 344; //supported
OP_NewTitlesAvailable = 345;
OP_NewZone = 346;
OP_OnLevelMessage = 347;
OP_OpenContainer = 348;
OP_OpenDiscordMerchant = 349;
OP_OpenGuildTributeMaster = 350;
OP_OpenInventory = 351;
OP_OpenNewTasksWindow = 352;
OP_OpenTributeMaster = 353;
OP_PDeletePetition = 354;
OP_PetBuffWindow = 355;
OP_PetCommands = 356;
OP_PetCommandState = 357;
OP_PetHoTT = 358;
OP_Petition = 359;
OP_PetitionBug = 360;
OP_PetitionCheckIn = 361;
OP_PetitionCheckout = 362;
OP_PetitionCheckout2 = 363;
OP_PetitionDelete = 364;
OP_PetitionQue = 365;
OP_PetitionRefresh = 366;
OP_PetitionResolve = 367;
OP_PetitionSearch = 368;
OP_PetitionSearchResults = 369;
OP_PetitionSearchText = 370;
OP_PetitionUnCheckout = 371;
OP_PetitionUpdate = 372;
OP_PickPocket = 373;
OP_PlayerProfile = 374;
OP_PlayerStateAdd = 375;
OP_PlayerStateRemove = 376;
OP_PlayEverquestRequest = 377;
OP_PlayEverquestResponse = 378;
OP_PlayMP3 = 379;
OP_Poll = 380;
OP_PollResponse = 381;
OP_PopupResponse = 382;
OP_PostEnterWorld = 383; //this is really OP_WorldAccessGrant
OP_PotionBelt = 384;
OP_PreLogoutReply = 385;
OP_PurchaseLeadershipAA = 386;
OP_PVPLeaderBoardDetailsReply = 387;
OP_PVPLeaderBoardDetailsRequest = 388;
OP_PVPLeaderBoardReply = 389;
OP_PVPLeaderBoardRequest = 390;
OP_PVPStats = 391;
OP_QueryResponseThing = 392;
OP_RaidInvite = 393;
OP_RaidJoin = 394;
OP_RaidUpdate = 395;
OP_RandomNameGenerator = 396;
OP_RandomReply = 397;
OP_RandomReq = 398;
OP_ReadBook = 399;
OP_RecipeAutoCombine = 400;
OP_RecipeDetails = 401;
OP_RecipeReply = 402;
OP_RecipesFavorite = 403;
OP_RecipesSearch = 404;
OP_ReclaimCrystals = 405;
OP_ReloadUI = 406;
OP_RemoveAllDoors = 407;
OP_RemoveBlockedBuffs = 408;
OP_RemoveNimbusEffect = 409;
OP_RemoveTrap = 410;
OP_Report = 411;
OP_ReqClientSpawn = 412;
OP_ReqNewZone = 413;
OP_RequestClientZoneChange = 414;
OP_RequestDuel = 415;
OP_RequestKnowledgeBase = 416;
OP_RequestTitles = 417;
OP_RespawnWindow = 418;
OP_RespondAA = 419;
OP_RestState = 420;
OP_Rewind = 421;
OP_RezzAnswer = 422;
OP_RezzComplete = 423;
OP_RezzRequest = 424;
OP_Sacrifice = 425;
OP_SafeFallSuccess = 426;
OP_SafePoint = 427;
OP_Save = 428;
OP_SaveOnZoneReq = 429;
OP_SelectTribute = 430;
OP_SendAAStats = 431;
OP_SendAATable = 432;
OP_SendCharInfo = 433;
OP_SendExpZonein = 434;
OP_SendFindableNPCs = 435;
OP_SendGuildTributes = 436;
OP_SendLoginInfo = 437;
OP_SendMaxCharacters = 438;
OP_SendMembership = 439;
OP_SendMembershipDetails = 440;
OP_SendSystemStats = 441;
OP_SendTitleList = 442;
OP_SendTributes = 443;
OP_SendZonepoints = 444;
OP_SenseHeading = 445;
OP_SenseTraps = 446;
OP_ServerListRequest = 447;
OP_ServerListResponse = 448;
OP_SessionReady = 449;
OP_SetChatServer = 450;
OP_SetChatServer2 = 451;
OP_SetGroupTarget = 452;
OP_SetGuildMOTD = 453;
OP_SetGuildRank = 454;
OP_SetRunMode = 455;
OP_SetServerFilter = 456;
OP_SetStartCity = 457;
OP_SetTitle = 458;
OP_SetTitleReply = 459;
OP_Shielding = 460;
OP_ShopDelItem = 461;
OP_ShopEnd = 462;
OP_ShopEndConfirm = 463;
OP_ShopItem = 464;
OP_ShopPlayerBuy = 465;
OP_ShopPlayerSell = 466;
OP_ShopRequest = 467;
OP_SimpleMessage = 468;
OP_SkillUpdate = 469;
OP_Sneak = 470;
OP_Some3ByteHPUpdate = 471;
OP_Some6ByteHPUpdate = 472;
OP_SomeItemPacketMaybe = 473;
OP_Sound = 474;
OP_SpawnAppearance = 475;
OP_SpawnDoor = 476;
OP_SpawnPositionUpdate = 477;
OP_SpecialMesg = 478;
OP_SpellEffect = 479;
OP_Split = 480;
OP_Stamina = 481;
OP_Stun = 482;
OP_Surname = 483;
OP_SwapSpell = 484;
OP_TargetBuffs = 485;
OP_TargetCommand = 486;
OP_TargetHoTT = 487;
OP_TargetMouse = 488;
OP_TargetReject = 489;
OP_TaskActivity = 490;
OP_TaskActivityComplete = 491;
OP_TaskDescription = 492;
OP_TaskHistoryReply = 493;
OP_TaskHistoryRequest = 494;
OP_TaskMemberList = 495;
OP_Taunt = 496;
OP_TestBuff = 497;
OP_TGB = 498;
OP_TimeOfDay = 499;
OP_Track = 500;
OP_TrackTarget = 501;
OP_TrackUnknown = 502;
OP_TradeAcceptClick = 503;
OP_TradeBusy = 504;
OP_TradeCoins = 505;
OP_TradeMoneyUpdate = 506;
OP_Trader = 507;
OP_TraderBuy = 508;
OP_TraderDelItem = 509;
OP_TradeRequest = 510;
OP_TradeRequestAck = 511;
OP_TraderItemUpdate = 512;
OP_TraderShop = 513;
OP_TradeSkillCombine = 514;
OP_Translocate = 515;
OP_TributeInfo = 516;
OP_TributeItem = 517;
OP_TributeMoney = 518;
OP_TributeNPC = 519;
OP_TributePointUpdate = 520;
OP_TributeTimer = 521;
OP_TributeToggle = 522;
OP_TributeUpdate = 523;
OP_Untargetable = 524;
OP_UpdateAA = 525;
OP_UpdateAura = 526;
OP_UpdateLeadershipAA = 527;
OP_VetClaimReply = 528;
OP_VetClaimRequest = 529;
OP_VetRewardsAvaliable = 530;
OP_VoiceMacroIn = 531;
OP_VoiceMacroOut = 532;
OP_WeaponEquip1 = 533;
OP_WearChange = 534; //supported
OP_Weather = 535;
OP_Weblink = 536;
OP_WhoAllRequest = 537;
OP_WhoAllResponse = 538;
OP_World_Client_CRC1 = 539;
OP_World_Client_CRC2 = 540;
OP_WorldClientReady = 541;
OP_WorldComplete = 542;
OP_WorldLogout = 543;
OP_WorldObjectsSent = 544;
OP_WorldUnknown001 = 545;
OP_XTargetAutoAddHaters = 546;
OP_XTargetOpen = 547;
OP_XTargetOpenResponse = 548;
OP_XTargetRequest = 549;
OP_XTargetResponse = 550;
OP_YellForHelp = 551;
OP_ZoneChange = 552;
OP_ZoneComplete = 553;
OP_ZoneEntry = 554; //supported
OP_ZoneGuildList = 555;
OP_ZoneInUnknown = 556;
OP_ZonePlayerToBind = 557;
OP_ZoneServerInfo = 558;
OP_ZoneServerReady = 559;
OP_ZoneSpawns = 560;
OP_ZoneUnavail = 561;
OP_ResetAA = 562;
OP_Buddy = 563;
OP_ChannelAnnounceJoin = 564;
OP_ChannelAnnounceLeave = 565;
OP_Ignore = 566;
OP_Mail = 567;
OP_MailboxChange = 568;
OP_MailDeliveryStatus = 569;
OP_MailHeader = 570;
OP_MailHeaderCount = 571;
OP_MailLogin = 572;
OP_MailNew = 573;
OP_MailSendBody = 574;
}
+19
View File
@@ -0,0 +1,19 @@
Hello World NATS example
## Go helloworld.go
* Install go and set your GOPATH/GOROOT variables as instructions notes. https://golang.org/doc/install
* run `go get ./...` in this directory
* run `go run helloworld.go` in this directory
## Python 2 helloworld2.py
* 2.7+ Python ideal
* run `pip install nats-client`
* run `pip install protobuf`
## C#
* The easiest way how to use C# protobuf is via the Google.Protobuf NuGet package. Just add the NuGet package to your VS project.
* Copy Message.cs to your project.
* NATS is obtained via the NATS.Client NuGet project
* (Optional) You will also want to install the Google.Protobuf.Tools NuGet package, which contains precompiled version of protoc.exe and a copy of well known .proto files under the package's tools directory.
* (Optional) To generate C# files from your .proto files, invoke protoc with the --csharp_out option.
* Read https://github.com/google/protobuf/tree/master/csharp for more details
@@ -0,0 +1,16 @@
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
tmp/
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
packages/
x64/
x86/
build/
bld/
[Bb]in/
[Oo]bj/
.vs
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>
+80
View File
@@ -0,0 +1,80 @@
namespace helloworld
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.TxtLog = new System.Windows.Forms.TextBox();
this.BtnHello = new System.Windows.Forms.Button();
this.TmrMessage = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
//
// TxtLog
//
this.TxtLog.Location = new System.Drawing.Point(13, 13);
this.TxtLog.Multiline = true;
this.TxtLog.Name = "TxtLog";
this.TxtLog.Size = new System.Drawing.Size(354, 151);
this.TxtLog.TabIndex = 0;
//
// BtnHello
//
this.BtnHello.Location = new System.Drawing.Point(12, 170);
this.BtnHello.Name = "BtnHello";
this.BtnHello.Size = new System.Drawing.Size(354, 64);
this.BtnHello.TabIndex = 1;
this.BtnHello.Text = "Hello World";
this.BtnHello.UseVisualStyleBackColor = true;
this.BtnHello.Click += new System.EventHandler(this.BtnHello_Click);
//
// TmrMessage
//
this.TmrMessage.Tick += new System.EventHandler(this.TmrMessage_Tick);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(380, 244);
this.Controls.Add(this.BtnHello);
this.Controls.Add(this.TxtLog);
this.Name = "Form1";
this.Text = "helloworld";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox TxtLog;
private System.Windows.Forms.Button BtnHello;
private System.Windows.Forms.Timer TmrMessage;
}
}
@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Eqproto;
using Google.Protobuf;
// Reference the NATS client.
using NATS.Client;
namespace helloworld
{
public partial class Form1 : Form
{
// Creates a live connection to the default
// NATS Server running locally
IConnection c;
ISyncSubscription sSync;
public Form1()
{
InitializeComponent();
}
private void BtnHello_Click(object sender, EventArgs e)
{
if (c != null && !c.IsClosed())
{
// Closing a connection
c.Close();
TxtLog.Text += "\r\nDisconnected.";
return;
}
TxtLog.Text = "Initialized";
// Create a new connection factory to create
// a connection.
ConnectionFactory cf = new ConnectionFactory();
c = cf.CreateConnection();
TxtLog.Text += "\r\nSending hello world";
ChannelMessage msg = new ChannelMessage();
msg.From = "csharp";
msg.Message = "Hello, World!";
msg.ChanNum = 5;
c.Publish("world.channel_message", msg.ToByteArray());
// Simple synchronous subscriber
sSync = c.SubscribeSync("world.channel_message");
TxtLog.Text += "\r\nWaiting for message...";
TmrMessage.Enabled = true;
}
private void TmrMessage_Tick(object sender, EventArgs e)
{
if (c == null || sSync == null)
{
return;
}
// Using a synchronous subscriber, gets the first message available,
// waiting up to 1000 milliseconds (1 second)
Msg m;
try
{
m = sSync.NextMessage(2);
Application.DoEvents();
} catch //(NATS.Client.NATSTimeoutException e)
{
return;
}
if (m == null) return;
ChannelMessage msg = ChannelMessage.Parser.ParseFrom(m.Data);
TxtLog.Text += string.Format("\r\nFrom: {0} Chan_num: {1} Message: {2}", msg.From, msg.ChanNum, msg.Message);
}
}
}
@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="TmrMessage.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace helloworld
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("helloworld")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("helloworld")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("7f2cb9a7-0e8a-486d-8443-e09038dbf872")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
@@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace helloworld.Properties
{
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("helloworld.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace helloworld.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}
@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7F2CB9A7-0E8A-486D-8443-E09038DBF872}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>helloworld</RootNamespace>
<AssemblyName>helloworld</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.5.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<HintPath>packages\Google.Protobuf.3.5.1\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="NATS.Client, Version=0.8.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\NATS.Client.0.8.0\lib\net45\NATS.Client.DLL</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="Message.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
@@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27428.2002
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "helloworld", "helloworld.csproj", "{7F2CB9A7-0E8A-486D-8443-E09038DBF872}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7F2CB9A7-0E8A-486D-8443-E09038DBF872}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7F2CB9A7-0E8A-486D-8443-E09038DBF872}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F2CB9A7-0E8A-486D-8443-E09038DBF872}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7F2CB9A7-0E8A-486D-8443-E09038DBF872}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3FE58E4E-B083-44A5-91B9-9E1F4E1EC6D4}
EndGlobalSection
EndGlobal
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.5.1" targetFramework="net461" />
<package id="Google.Protobuf.Tools" version="3.5.1" targetFramework="net461" />
<package id="NATS.Client" version="0.8.0" targetFramework="net461" />
<package id="System.Runtime.Serialization.Json" version="4.0.2" targetFramework="net461" />
</packages>
+80
View File
@@ -0,0 +1,80 @@
package main
import (
"fmt"
"log"
"time"
"github.com/eqemu/server/protobuf/go/eqproto"
"github.com/golang/protobuf/proto"
"github.com/nats-io/go-nats"
)
func main() {
fmt.Println("Starting...")
var nc *nats.Conn
var err error
//create a nats connection, by default 127.0.0.1
if nc, err = nats.Connect(nats.DefaultURL); err != nil {
log.Fatal(err)
}
defer nc.Close()
//listen for any channel messages from game
go asyncChannelMessageSubscriber(nc) //async is recommended
//go syncChannelMessageSubscriber() //sync is here as example
//send a channel message to broadcast channel
go testBroadcastMessage(nc, "Hello, World!")
time.Sleep(100 * time.Second)
fmt.Println("Exited after 100 seconds")
}
// asyncChannelMessageSubscriber is an example of how to subscribe
// and invoke a function when a message is received
func asyncChannelMessageSubscriber(nc *nats.Conn) {
nc.Subscribe("world.channel_message.out", func(m *nats.Msg) {
message := &eqproto.ChannelMessage{}
proto.Unmarshal(m.Data, message)
log.Println(message)
})
log.Println("Waiting on async messages...")
}
// syncChannelMessageSubscriber is an example of how to subscribe
// and poll for messages syncronously
func syncChannelMessageSubscriber(nc *nats.Conn) {
sub, err := nc.SubscribeSync("world.channel_message.out")
if err != nil {
log.Fatal(err)
}
var m *nats.Msg
if m, err = sub.NextMsg(10 * time.Second); err != nil {
log.Println("Timed out after 10 seconds waiting for message", err.Error())
return
}
message := &eqproto.ChannelMessage{}
proto.Unmarshal(m.Data, message)
log.Println("Got message", message)
}
func testBroadcastMessage(nc *nats.Conn, msg string) {
message := &eqproto.ChannelMessage{
From: "go",
Message: msg,
Number: 5, //5 is ooc, 6 is bc
}
d, err := proto.Marshal(message)
if err != nil {
log.Fatal(err)
}
if err = nc.Publish("world.channel_message.in", d); err != nil {
log.Println("Failed to publish:", err.Error())
return
}
log.Println("Sending message", message)
}
+47
View File
@@ -0,0 +1,47 @@
# coding: utf-8
import tornado.ioloop
import tornado.gen
import time
import sys
sys.path.insert(0, "../../../protobuf/python/proto")
from datetime import datetime
from nats.io.utils import new_inbox
from nats.io import Client as NATS
import message_pb2
@tornado.gen.coroutine
def main():
nc = NATS()
# Establish connection to the server.
options = { "verbose": True, "servers": ["nats://127.0.0.1:4222"] }
yield nc.connect(**options)
def discover(msg=None):
channel_message = message_pb2.ChannelMessage()
channel_message.ParseFromString(msg.data)
print("[Received]: %s" % channel_message)
send_message = message_pb2.ChannelMessage()
send_message.chan_num = 5
#send_message.from = "python"
send_message.message = "Hello, World!"
sid = yield nc.subscribe("world.channel_message", "", discover)
yield nc.publish("world.channel_message", send_message.SerializeToString())
loop = tornado.ioloop.IOLoop.instance()
yield tornado.gen.Task(loop.add_timeout, time.time() + 20)
try:
start = datetime.now()
# Make roundtrip to the server and timeout after 1 second
yield nc.flush(1)
end = datetime.now()
print("Latency: %d µs" % (end.microsecond - start.microsecond))
except tornado.gen.TimeoutError, e:
print("Timeout! Roundtrip too slow...")
if __name__ == '__main__':
tornado.ioloop.IOLoop.instance().run_sync(main)
+256
View File
@@ -0,0 +1,256 @@
//Makes a player walk around in ecommons near Guard Reskin
package main
import (
"fmt"
"log"
"strconv"
"strings"
"time"
"github.com/eqemu/server/protobuf/go/eqproto"
"github.com/golang/protobuf/proto"
"github.com/nats-io/go-nats"
)
var (
nc *nats.Conn
err error
entities []*eqproto.Entity
)
func main() {
if nc, err = nats.Connect(nats.DefaultURL); err != nil {
log.Fatal(err)
}
defer nc.Close()
zone := "ecommons"
instance := 0
entityID := int64(288)
entities = zoneEntityList(zone, 0)
fmt.Println(len(entities), "entities known")
var attackEntityID int64
for _, entity := range entities {
if entity.Name == "Guard_Reskin000" {
fmt.Println("Found guard reskin as ID", entity.Id)
attackEntityID = int64(entity.Id)
break
}
}
if attackEntityID == 0 {
log.Fatal("Can't find guard to attack!")
}
entityID = zoneCommandEntity(zone, "spawn", []string{
"146.17",
"-112.51",
"-52.01",
"109.6",
"GoSpawn",
})
if entityID == 0 {
log.Fatal("failed to get entity ID!")
}
go testMoveToLoop(zone, entityID)
go testAttack(zone, entityID, attackEntityID)
go entityEventSubscriber(zone, instance, entityID)
time.Sleep(1000 * time.Second)
}
//testMoveToLoop causes an npc to go in a circle in pojustice
func testMoveToLoop(zone string, entityID int64) {
params := []string{}
positions := []string{
"156.72 -136.71 -52.02 112.8",
"116.18 -101.56 -51.56 228.8",
"151.37 -102.54 -52.01 228.8",
}
command := "moveto"
curPos := 0
for {
curPos++
fmt.Println("Moving to position", curPos)
if len(positions) < curPos+1 {
fmt.Println("Resetting position")
curPos = 0
}
params = []string{}
params = append(params, fmt.Sprintf("%d", entityID))
params = append(params, strings.Split(positions[curPos], " ")...)
zoneCommand(zone, command, params)
time.Sleep(5 * time.Second)
}
}
func testAttack(zone string, entityID int64, targetID int64) {
time.Sleep(10 * time.Second)
fmt.Println("10 seconds, Having", entityID, "attack", targetID)
params := []string{
fmt.Sprintf("%d", entityID),
fmt.Sprintf("%d", targetID), //attack first element
"1", //amount of hate
}
command := "attack"
zoneCommand(zone, command, params)
}
func zoneEntityList(zone string, instanceID int) (entities []*eqproto.Entity) {
msg := &eqproto.CommandMessage{
Author: "xackery",
Command: "entitylist",
Params: []string{"npc"},
}
d, err := proto.Marshal(msg)
if err != nil {
log.Fatal(err)
}
channel := fmt.Sprintf("zone.%s.command_message.in", zone)
reply, err := nc.Request(channel, d, 1*time.Second)
if err != nil {
log.Println("Failed to get response on", channel, "", err.Error())
return
}
err = proto.Unmarshal(reply.Data, msg)
if err != nil {
fmt.Println("Failed to unmarshal", err.Error())
return
}
rootEntities := &eqproto.Entities{}
err = proto.Unmarshal([]byte(msg.Payload), rootEntities)
if err != nil {
fmt.Println("failed to unmarshal entities", err.Error(), msg)
return
}
entities = rootEntities.Entities
return
}
func zoneCommandEntity(zone string, command string, params []string) (entityID int64) {
msg := &eqproto.CommandMessage{
Author: "xackery",
Command: command,
Params: params,
}
d, err := proto.Marshal(msg)
if err != nil {
log.Fatal(err)
}
reply, err := nc.Request(fmt.Sprintf("zone.%s.command_message.in", zone), d, 1*time.Second)
if err != nil {
log.Println("Failed to get request response:", err.Error())
return
}
err = proto.Unmarshal(reply.Data, msg)
if err != nil {
fmt.Println("Failed to unmarshal", err.Error())
return
}
fmt.Println("Response:", msg)
entityID, err = strconv.ParseInt(msg.Result, 10, 64)
if err != nil {
fmt.Println("Failed to parse response", err.Error(), msg.Result)
return
}
return
}
func zoneCommand(zone string, command string, params []string) {
msg := &eqproto.CommandMessage{
Author: "xackery",
Command: command,
Params: params,
}
d, err := proto.Marshal(msg)
if err != nil {
log.Fatal(err)
}
reply, err := nc.Request(fmt.Sprintf("zone.%s.command_message.in", zone), d, 1*time.Second)
if err != nil {
log.Println("Failed to get request response:", err.Error())
return
}
err = proto.Unmarshal(reply.Data, msg)
if err != nil {
fmt.Println("Failed to unmarshal", err.Error())
return
}
fmt.Println("Response:", msg)
return
}
func entityEventSubscriber(zone string, instance int, entityID int64) {
/*event := &eqproto.EntityEvent{
Entity: &eqproto.Entity{
Id: 1,
},
}
d, err := proto.Marshal(event)
if err != nil {
log.Fatal(err)
}
if err = nc.Publish(fmt.Sprintf("zone.%s.entity.event_subscribe.all", zone), d); err != nil {
log.Println("Failed to publish event subscribe:", err.Error())
return
}*/
var opCode int64
var index int
channel := fmt.Sprintf("zone.%s.%d.entity.%d.event.out", zone, instance, entityID)
nc.Subscribe(channel, func(m *nats.Msg) {
event := &eqproto.Event{}
err = proto.Unmarshal(m.Data, event)
if err != nil {
fmt.Println("invalid event data passed", m.Data)
}
var eventPayload proto.Message
switch event.Op {
case eqproto.OpCode_OP_ClientUpdate:
eventPayload = &eqproto.PlayerPositionUpdateEvent{}
case eqproto.OpCode_OP_Animation:
eventPayload = &eqproto.AnimationEvent{}
case eqproto.OpCode_OP_NewSpawn:
eventPayload = &eqproto.SpawnEvent{}
case eqproto.OpCode_OP_ZoneEntry:
eventPayload = &eqproto.SpawnEvent{}
case eqproto.OpCode_OP_HPUpdate:
eventPayload = &eqproto.HPEvent{}
case eqproto.OpCode_OP_MobHealth:
eventPayload = &eqproto.HPEvent{}
case eqproto.OpCode_OP_DeleteSpawn:
eventPayload = &eqproto.DeleteSpawnEvent{}
case eqproto.OpCode_OP_Damage:
eventPayload = &eqproto.DamageEvent{}
case eqproto.OpCode_OP_SpecialMesg:
eventPayload = &eqproto.SpecialMessageEvent{}
default:
return
}
err = proto.Unmarshal(event.Payload, eventPayload)
if err != nil {
fmt.Println("Invalid data passed for opcode", eqproto.OpCode(opCode), err.Error(), string(m.Data[index+1:]))
return
}
fmt.Println(m.Subject, event.Op, eventPayload)
//log.Printf("Received a message on %s: %s\n", m.Subject, string(m.Data))
//proto.Unmarshal(m.Data, event)
//log.Println(event.Op.String(), event.Entity, event.Target)
})
log.Println("Subscribed to", channel, ", waiting on messages...")
time.Sleep(500 * time.Second)
}
+308
View File
@@ -0,0 +1,308 @@
//Makes a player say a message in local chat
package main
import (
"fmt"
"log"
"time"
"github.com/eqemu/server/protobuf/go/eqproto"
"github.com/golang/protobuf/proto"
"github.com/nats-io/go-nats"
"github.com/pkg/errors"
)
var (
nc *nats.Conn
err error
entities []*eqproto.Entity
)
func main() {
if nc, err = nats.Connect(nats.DefaultURL); err != nil {
log.Fatal(err)
}
defer nc.Close()
zone := "ecommons"
instance := int64(0)
entities = zoneEntityList(zone, 0)
if len(entities) == 0 {
return
}
fmt.Println(len(entities), "entities known")
//fmt.Println(entities)
var entityID int32
for _, entity := range entities {
if entity.Name == "Shin" {
fmt.Println("Found Shin as ID", entity.Id)
entityID = entity.Id
break
}
}
if entityID == 0 {
log.Fatal("Can't find entity!")
}
go asyncChannelMessageSubscriber(nc) //async is recommended
go entityEventSubscriber(zone, instance, entityID)
err := zoneChannelMessage(zone, instance, entityID, eqproto.EntityType_Client, eqproto.MessageType_Say, "Hello, World!")
//err := tell("shin", "Testing tell")
if err != nil {
fmt.Println("Failed to send channel message:", err.Error())
return
}
time.Sleep(1000 * time.Second)
}
func tell(to string, message string) (err error) {
msg := &eqproto.ChannelMessage{
Message: message,
From: "go",
To: to,
}
d, err := proto.Marshal(msg)
if err != nil {
log.Fatal(err)
}
channel := fmt.Sprintf("world.channel_message.in")
reply, err := nc.Request(channel, d, 1*time.Second)
if err != nil {
err = errors.Wrap(err, "Failed to get request response on zone channel")
return
}
err = proto.Unmarshal(reply.Data, msg)
if err != nil {
err = errors.Wrap(err, "failed to unmarshal")
return
}
if msg.ResponseError > 0 {
err = errors.New(msg.ResponseMessage)
return
}
fmt.Println("Response:", msg)
return
}
func zoneChannelMessage(zone string, instance int64, fromEntityID int32, fromEntityType eqproto.EntityType, chanNumber eqproto.MessageType, message string) (err error) {
msg := &eqproto.ChannelMessage{
Message: message,
Number: eqproto.MessageType_SayLocal, //chanNumber,
FromEntityId: fromEntityID,
FromEntityType: fromEntityType,
From: "go",
Distance: 500,
SkipSender: false,
//To: "shin",
}
d, err := proto.Marshal(msg)
if err != nil {
log.Fatal(err)
}
channel := fmt.Sprintf("zone.%s.%d.channel_message.in", zone, instance)
reply, err := nc.Request(channel, d, 1*time.Second)
if err != nil {
err = errors.Wrap(err, "Failed to get request response on zone channel")
return
}
err = proto.Unmarshal(reply.Data, msg)
if err != nil {
err = errors.Wrap(err, "failed to unmarshal")
return
}
if msg.ResponseError > 0 {
err = errors.New(msg.ResponseMessage)
return
}
fmt.Println("Response:", msg)
return
}
func testAttack(zone string, entityID int64, targetID int64) {
time.Sleep(10 * time.Second)
fmt.Println("10 seconds, Having", entityID, "attack", targetID)
params := []string{
fmt.Sprintf("%d", entityID),
fmt.Sprintf("%d", targetID), //attack first element
"1", //amount of hate
}
command := "attack"
zoneCommand(zone, command, params)
}
func zoneEntityList(zone string, instanceID int) (entities []*eqproto.Entity) {
msg := &eqproto.CommandMessage{
Author: "xackery",
Command: "entitylist",
Params: []string{"client"},
}
d, err := proto.Marshal(msg)
if err != nil {
log.Fatal(err)
}
channel := fmt.Sprintf("zone.%s.command_message.in", zone)
reply, err := nc.Request(channel, d, 1*time.Second)
if err != nil {
log.Println("Failed to get response on", channel, err.Error())
return
}
err = proto.Unmarshal(reply.Data, msg)
if err != nil {
fmt.Println("Failed to unmarshal", err.Error())
return
}
if msg.ResponseError > 0 {
fmt.Println("Failed to get entity list:", msg.ResponseError, msg.ResponseMessage)
return
}
//fmt.Println("reply", len(msg.Payload), string(msg.Payload))
rootEntities := &eqproto.Entities{}
err = proto.Unmarshal([]byte(msg.ResponsePayload), rootEntities)
if err != nil {
fmt.Println("failed to unmarshal entities", err.Error(), msg)
return
}
entities = rootEntities.Entities
return
}
func zoneCommandEntity(zone string, command string, params []string) (entityID int32) {
msg := &eqproto.CommandMessage{
Author: "xackery",
Command: command,
Params: params,
}
d, err := proto.Marshal(msg)
if err != nil {
log.Fatal(err)
}
reply, err := nc.Request(fmt.Sprintf("zone.%s.command_message.in", zone), d, 1*time.Second)
if err != nil {
log.Println("Failed to get request response:", err.Error())
return
}
err = proto.Unmarshal(reply.Data, msg)
if err != nil {
fmt.Println("Failed to unmarshal", err.Error())
return
}
//fmt.Println("Response:", msg)
if msg.ResponseError > 0 {
fmt.Println("Failed to get response:", msg.ResponseError, msg.ResponseMessage)
return
}
entityID = msg.ResponseValue
return
}
func zoneCommand(zone string, command string, params []string) {
msg := &eqproto.CommandMessage{
Author: "xackery",
Command: command,
Params: params,
}
d, err := proto.Marshal(msg)
if err != nil {
log.Fatal(err)
}
reply, err := nc.Request(fmt.Sprintf("zone.%s.command_message.in", zone), d, 1*time.Second)
if err != nil {
log.Println("Failed to get request response:", err.Error())
return
}
err = proto.Unmarshal(reply.Data, msg)
if err != nil {
fmt.Println("Failed to unmarshal", err.Error())
return
}
fmt.Println("Response:", msg)
return
}
func entityEventSubscriber(zone string, instance int64, entityID int32) {
var index int
channel := fmt.Sprintf("zone.%s.%d.entity.%d.event.out", zone, instance, entityID)
nc.Subscribe(channel, func(m *nats.Msg) {
event := &eqproto.Event{}
err = proto.Unmarshal(m.Data, event)
if err != nil {
fmt.Println("invalid event data passed", m.Data)
return
}
var eventPayload proto.Message
switch event.Op {
case eqproto.OpCode_OP_ClientUpdate:
eventPayload = &eqproto.PlayerPositionUpdateEvent{}
case eqproto.OpCode_OP_Animation:
eventPayload = &eqproto.AnimationEvent{}
case eqproto.OpCode_OP_NewSpawn:
eventPayload = &eqproto.SpawnEvent{}
case eqproto.OpCode_OP_ZoneEntry:
eventPayload = &eqproto.SpawnEvent{}
case eqproto.OpCode_OP_HPUpdate:
eventPayload = &eqproto.HPEvent{}
case eqproto.OpCode_OP_MobHealth:
eventPayload = &eqproto.HPEvent{}
case eqproto.OpCode_OP_DeleteSpawn:
eventPayload = &eqproto.DeleteSpawnEvent{}
case eqproto.OpCode_OP_Damage:
eventPayload = &eqproto.DamageEvent{}
case eqproto.OpCode_OP_SpecialMesg:
eventPayload = &eqproto.SpecialMessageEvent{}
case eqproto.OpCode_OP_ChannelMessage:
eventPayload = &eqproto.ChannelMessageEvent{}
default:
return
}
err = proto.Unmarshal(event.Payload, eventPayload)
if err != nil {
fmt.Println("Invalid data passed for opcode", event.Op, err.Error(), string(m.Data[index+1:]))
return
}
fmt.Println(m.Subject, event.Op, eventPayload)
//log.Printf("Received a message on %s: %s\n", m.Subject, string(m.Data))
//proto.Unmarshal(m.Data, event)
//log.Println(event.Op.String(), event.Entity, event.Target)
})
log.Println("Subscribed to", channel, ", waiting on messages...")
time.Sleep(500 * time.Second)
}
// asyncChannelMessageSubscriber is an example of how to subscribe
// and invoke a function when a message is received
func asyncChannelMessageSubscriber(nc *nats.Conn) {
nc.Subscribe("world.channel_message.out", func(m *nats.Msg) {
message := &eqproto.ChannelMessage{}
proto.Unmarshal(m.Data, message)
log.Println(message)
})
nc.Subscribe("zone.ecommons.0.channel_message.out", func(m *nats.Msg) {
message := &eqproto.ChannelMessage{}
proto.Unmarshal(m.Data, message)
log.Println(message)
})
log.Println("Waiting on async messages...")
}
+2
View File
@@ -13,6 +13,7 @@ SET(world_sources
lfplist.cpp
login_server.cpp
login_server_list.cpp
nats_manager.cpp
net.cpp
queryserv.cpp
ucs.cpp
@@ -40,6 +41,7 @@ SET(world_headers
lfplist.h
login_server.h
login_server_list.h
nats_manager.h
net.h
queryserv.h
sof_char_create_data.h
+4
View File
@@ -46,6 +46,7 @@
#include "clientlist.h"
#include "wguild_mgr.h"
#include "sof_char_create_data.h"
#include "nats_manager.h"
#include <iostream>
#include <iomanip>
@@ -83,6 +84,7 @@ extern LoginServerList loginserverlist;
extern ClientList client_list;
extern EQEmu::Random emu_random;
extern uint32 numclients;
extern NatsManager nats;
extern volatile bool RunLoops;
extern volatile bool UCSServerAvailable_;
@@ -800,6 +802,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
}
else {
Log(Logs::Detail, Logs::World_Server, "'%s' is trying to go home before they're able...", char_name);
nats.SendAdminMessage(StringFormat("Hacker: %s [%s]: MQGoHome: player tried to go home before they were able.", GetAccountName(), char_name));
database.SetHackerFlag(GetAccountName(), char_name, "MQGoHome: player tried to go home before they were able.");
eqs->Close();
return true;
@@ -824,6 +827,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
}
else {
Log(Logs::Detail, Logs::World_Server, "'%s' is trying to go to tutorial but are not allowed...", char_name);
nats.SendAdminMessage(StringFormat("Hacker %s [%s]: MQTutorial: player tried to enter the tutorial without having tutorial enabled for this character.", GetAccountName(), char_name));
database.SetHackerFlag(GetAccountName(), char_name, "MQTutorial: player tried to enter the tutorial without having tutorial enabled for this character.");
eqs->Close();
return true;
+3
View File
@@ -25,10 +25,12 @@
#include "world_config.h"
#include "../common/guilds.h"
#include "../common/string_util.h"
#include "nats_manager.h"
extern uint32 numplayers;
extern LoginServerList loginserverlist;
extern ClientList client_list;
extern NatsManager nats;
extern volatile bool RunLoops;
ClientListEntry::ClientListEntry(uint32 in_id, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin, uint32 ip, uint8 local)
@@ -286,6 +288,7 @@ bool ClientListEntry::CheckAuth(uint32 iLSID, const char* iKey) {
Log(Logs::Detail, Logs::World_Server,"Error adding local account for LS login: '%s', duplicate name?" ,plsname);
return false;
}
nats.SendAdminMessage(StringFormat("New account was created for %s, accountid: %u", plsname, paccountid));
strn0cpy(paccountname, plsname, sizeof(paccountname));
padmin = tmpStatus;
}
+55
View File
@@ -1467,4 +1467,59 @@ void ClientList::OnTick(EQ::Timer *t)
}
web_interface.SendEvent(out);
}
std::string ClientList::GetWhoAll() {
std::string reply = "";
LinkedListIterator<ClientListEntry*> iterator(clientlist);
ClientListEntry* cle = 0;
uint32 x = 0;
char* output = 0;
uint32 outsize = 0, outlen = 0;
reply.append("Players on server:\n");
iterator.Reset();
while (iterator.MoreElements()) {
cle = iterator.GetData();
const char* tmpZone = database.GetZoneName(cle->zone());
if (cle->Online() < CLE_Status_Zoning ||
x > 20) {
iterator.Advance();
continue;
}
if (cle->Admin() >= 250) reply.append("* GM-Impossible * ");
else if (cle->Admin() >= 200) reply.append("* GM-Mgmt * ");
else if (cle->Admin() >= 180) reply.append("* GM-Coder * ");
else if (cle->Admin() >= 170) reply.append("* GM-Areas * ");
else if (cle->Admin() >= 160) reply.append("* QuestMaster * ");
else if (cle->Admin() >= 150) reply.append("* GM-Lead Admin * ");
else if (cle->Admin() >= 100) reply.append("* GM-Admin * ");
else if (cle->Admin() >= 95) reply.append("* GM-Staff * ");
else if (cle->Admin() >= 90) reply.append("* EQ Support * ");
else if (cle->Admin() >= 85) reply.append("* GM-Tester * ");
else if (cle->Admin() >= 81) reply.append("* Senior Guide * ");
else if (cle->Admin() >= 80) reply.append("* QuestTroupe * ");
else if (cle->Admin() >= 50) reply.append("* Guide * ");
//else if (cle->Admin() >= 20) reply.append("* Apprentice Guide * ");
//else if (cle->Admin() >= 10) reply.append("* Steward * ");
if (cle->Anon() == 2) reply.append("[RolePlay");
else if (cle->Anon() == 1) reply.append("[ANON");
else reply.append("[");
reply.append(StringFormat(" %i %s ] %s", cle->level(), GetClassIDName(cle->class_(), cle->level()), cle->name()));
reply.append(StringFormat(" %s zone: %s", GetRaceIDName(cle->race()), database.GetZoneName(cle->zone())));
if (guild_mgr.GuildExists(cle->GuildID())) reply.append(StringFormat(" <%s>", guild_mgr.GetGuildName(cle->GuildID())));
if (cle->LFG()) reply.append(" LFG");
reply.append("\n");
x++;
iterator.Advance();
}
if (x >= 20) reply.append("First 20 shown, ");
reply.append(StringFormat("%u total players online.", x));
return reply;
}
+1
View File
@@ -69,6 +69,7 @@ public:
int GetClientCount();
void GetClients(const char *zone_name, std::vector<ClientListEntry *> &into);
std::string GetWhoAll();
private:
void OnTick(EQ::Timer *t);
inline uint32 GetNextCLEID() { return NextCLEID++; }
+386
View File
@@ -0,0 +1,386 @@
#include "nats_manager.h"
#include "nats.h"
#include "zonelist.h"
#include "login_server_list.h"
#include "clientlist.h"
#include "cliententry.h"
#include "worlddb.h"
#include <google/protobuf/arena.h>
#include "../common/seperator.h"
#include "../common/eqemu_logsys.h"
#ifndef PROTO_H
#define PROTO_H
#include "../common/message.pb.h"
#endif
#include "../common/servertalk.h"
#include "../common/string_util.h"
extern ZSList zoneserver_list;
extern LoginServerList loginserverlist;
extern ClientList client_list;
const WorldConfig *worldConfig;
google::protobuf::Arena the_arena;
NatsManager::NatsManager()
{
//new timers, object initialization
worldConfig = WorldConfig::get();
}
NatsManager::~NatsManager()
{
// Destroy all our objects to avoid report of memory leak
natsStatistics_Destroy(stats);
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
// To silence reports of memory still in used with valgrind
nats_Close();
}
bool NatsManager::connect() {
auto ncs = natsConnection_Status(conn);
if (ncs == CONNECTED)
return true;
if (nats_timer.Enabled() && !nats_timer.Check())
return false;
natsOptions *opts = NULL;
natsOptions_Create(&opts);
natsOptions_SetMaxReconnect(opts, 0);
natsOptions_SetReconnectWait(opts, 0);
natsOptions_SetAllowReconnect(opts, false);
//The timeout is going to cause a 100ms delay on all connected clients every X seconds (20s)
//since this blocks the connection. It can be set lower or higher delay,
//but since NATS is a second priority I wanted server impact minimum.
natsOptions_SetTimeout(opts, 100);
std::string connection = StringFormat("nats://%s:%d", worldConfig->NATSHost.c_str(), worldConfig->NATSPort);
if (worldConfig->NATSHost.length() == 0)
connection = "nats://localhost:4222";
natsOptions_SetURL(opts, connection.c_str());
s = natsConnection_Connect(&conn, opts);
natsOptions_Destroy(opts);
if (s != NATS_OK) {
Log(Logs::General, Logs::NATS, "failed to connect to %s: %s, retrying in 20s", connection.c_str(), nats_GetLastError(&s));
conn = NULL;
nats_timer.Enable();
nats_timer.SetTimer(20000);
return false;
}
Log(Logs::General, Logs::NATS, "connected to %s", connection.c_str());
nats_timer.Disable();
s = natsConnection_SubscribeSync(&channelMessageSub, conn, "world.channel_message.in");
if (s != NATS_OK)
Log(Logs::General, Logs::NATS, "world.channel_message.in: failed to subscribe: %s", nats_GetLastError(&s));
s = natsConnection_SubscribeSync(&commandMessageSub, conn, "world.command_message.in");
if (s != NATS_OK)
Log(Logs::General, Logs::NATS, "world.command_message.in: failed to subscribe: %s", nats_GetLastError(&s));
return true;
}
void NatsManager::Process()
{
natsMsg *msg = NULL;
if (!connect())
return;
s = NATS_OK;
for (int count = 0; (s == NATS_OK) && count < 5; count++)
{
s = natsSubscription_NextMsg(&msg, channelMessageSub, 1);
if (s != NATS_OK)
break;
eqproto::ChannelMessage* message = google::protobuf::Arena::CreateMessage<eqproto::ChannelMessage>(&the_arena);
if (!message->ParseFromArray(natsMsg_GetData(msg), natsMsg_GetDataLength(msg))) {
Log(Logs::General, Logs::NATS, "world.channel_message.in: failed to parse");
natsMsg_Destroy(msg);
continue;
}
GetChannelMessage(message, natsMsg_GetReply(msg));
}
s = NATS_OK;
for (int count = 0; (s == NATS_OK) && count < 5; count++)
{
s = natsSubscription_NextMsg(&msg, commandMessageSub, 1);
if (s != NATS_OK)
break;
eqproto::CommandMessage* message = google::protobuf::Arena::CreateMessage<eqproto::CommandMessage>(&the_arena);
if (!message->ParseFromArray(natsMsg_GetData(msg), natsMsg_GetDataLength(msg))) {
Log(Logs::General, Logs::NATS, "world.command_message.in: failed to parse");
natsMsg_Destroy(msg);
continue;
}
GetCommandMessage(message, natsMsg_GetReply(msg));
}
}
void NatsManager::OnChannelMessage(ServerChannelMessage_Struct* msg) {
if (!connect())
return;
eqproto::ChannelMessage* message = google::protobuf::Arena::CreateMessage<eqproto::ChannelMessage>(&the_arena);
message->set_fromadmin(msg->fromadmin);
message->set_deliverto(msg->deliverto);
message->set_guilddbid(msg->guilddbid);
message->set_noreply(msg->noreply);
message->set_queued(msg->queued);
message->set_number(static_cast<eqproto::MessageType>(msg->chan_num));
message->set_message(msg->message);
message->set_to(msg->to);
message->set_language(msg->language);
message->set_from(msg->from);
SendChannelMessage(message);
return;
}
void NatsManager::OnEmoteMessage(ServerEmoteMessage_Struct* msg) {
if (!connect())
return;
eqproto::ChannelMessage* message = google::protobuf::Arena::CreateMessage<eqproto::ChannelMessage>(&the_arena);
message->set_guilddbid(msg->guilddbid);
message->set_minstatus(msg->minstatus);
message->set_type(msg->type);
message->set_message(msg->message);
message->set_to(msg->to);
message->set_is_emote(true);
//SendChannelMessage(message);
return;
}
// SendAdminMessage will send an admin message to NATS
void NatsManager::SendAdminMessage(std::string adminMessage, const char* reply) {
if (!connect())
return;
eqproto::ChannelMessage* message = google::protobuf::Arena::CreateMessage<eqproto::ChannelMessage>(&the_arena);
message->set_message(adminMessage.c_str());
size_t event_size = message->ByteSizeLong();
void *event_buffer = malloc(event_size);
if (!message->SerializeToArray(event_buffer, event_size)) {
Log(Logs::General, Logs::NATS, "global.admin_message.out: failed to serialize message");
return;
}
if (reply && strlen(reply) > 0)
s = natsConnection_Publish(conn, reply, event_buffer, event_size);
else
s = natsConnection_Publish(conn, "global.admin_message.out", event_buffer, event_size);
if (s != NATS_OK) {
Log(Logs::General, Logs::NATS, "global.admin_message.out failed: %s", nats_GetLastError(&s));
return;
}
Log(Logs::General, Logs::NATS, "global.admin_message.out: %s", adminMessage.c_str());
}
// SendCommandMessage will send a channel message to NATS
void NatsManager::SendCommandMessage(eqproto::CommandMessage* message, const char* reply) {
if (!connect())
return;
size_t event_size = message->ByteSizeLong();
void *event_buffer = malloc(event_size);
if (!message->SerializeToArray(event_buffer, event_size)) {
Log(Logs::General, Logs::NATS, "global.admin_message.out: failed to serialize message");
return;
}
if (reply && strlen(reply) > 0)
s = natsConnection_Publish(conn, reply, event_buffer, event_size);
else
s = natsConnection_Publish(conn, "world.command_message.out", event_buffer, event_size);
if (s != NATS_OK) {
Log(Logs::General, Logs::NATS, "world.command_message.out failed: %s", nats_GetLastError(&s));
return;
}
Log(Logs::General, Logs::NATS, "world.command_message.in: %s (%d: %s)", message->command().c_str(), message->response_error(), message->response_message().c_str());
}
// GetCommandMessage is used to process a command message
void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char* reply) {
if (!connect())
return;
if (message->command().compare("who") == 0) {
message->set_response_message(client_list.GetWhoAll());
SendCommandMessage(message, reply);
return;
}
if (message->command().compare("unlock") == 0) {
WorldConfig::UnlockWorld();
if (loginserverlist.Connected())
loginserverlist.SendStatus();
message->set_response_message("Server is now unlocked.");
SendCommandMessage(message, reply);
return;
}
if (message->command().compare("lock") == 0) {
WorldConfig::LockWorld();
if (loginserverlist.Connected())
loginserverlist.SendStatus();
message->set_response_message("Server is now locked.");
SendCommandMessage(message, reply);
return;
}
if(message->command().compare("worldshutdown") == 0) {
uint32 time=0;
uint32 interval=0;
if(message->params_size() == 2 && ((time=atoi(message->params(0).c_str()))>0) && ((interval=atoi(message->params(1).c_str()))>0)) {
message->set_response_message(StringFormat("Sending shutdown packet now, World will shutdown in: %i minutes with an interval of: %i seconds", (time / 60), interval));
zoneserver_list.WorldShutDown(time, interval);
SendCommandMessage(message, reply);
return;
}
else if(strcasecmp(message->params(0).c_str(), "now") == 0){
message->set_response_message("Sending shutdown packet now");
zoneserver_list.WorldShutDown(0, 0);
SendCommandMessage(message, reply);
return;
}
else if(strcasecmp(message->params(0).c_str(), "disable") == 0){
message->set_response_message("Shutdown prevented, next time I may not be so forgiving...");
zoneserver_list.SendEmoteMessage(0, 0, 0, 15, "<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World shutdown aborted.");
zoneserver_list.shutdowntimer->Disable();
zoneserver_list.reminder->Disable();
SendCommandMessage(message, reply);
return;
}
message->set_response_error(eqproto::ERR_Request);
message->set_response_message("worldshutdown - Shuts down the server and all zones.\n \
Usage: worldshutdown now - Shuts down the server and all zones immediately.\n \
Usage: worldshutdown disable - Stops the server from a previously scheduled shut down.\n \
Usage: worldshutdown [timer] [interval] - Shuts down the server and all zones after [timer] seconds and sends warning every [interval] seconds\n");
SendCommandMessage(message, reply);
return;
}
message->set_response_error(eqproto::ERR_Request);
message->set_response_message("Unknown command");
SendCommandMessage(message, reply);
return;
}
// GetChannelMessage is when a 3rd party app sends a channel message via NATS.
void NatsManager::GetChannelMessage(eqproto::ChannelMessage* message, const char* reply) {
if (!connect())
return;
if (message->is_emote()) { //emote message
zoneserver_list.SendEmoteMessage(message->to().c_str(), message->guilddbid(), message->minstatus(), message->type(), message->message().c_str());
message->set_response_message("Success");
SendChannelMessage(message, reply);
return;
}
//normal broadcast
char from[64];
from[0] = '*';
strcpy(&from[1], message->from().c_str());
int channel = message->number();
if (channel < 1 && message->guilddbid() < 1) {
channel = MT_OOC; //default to ooc
message->set_number(eqproto::OOC);
}
if (message->to().length() == 0) { //Send a world message
zoneserver_list.SendChannelMessage(from, 0, channel, message->language(), message->message().c_str());
message->set_response_message("Success");
SendChannelMessage(message, reply);
return;
}
//Send a tell
channel = 7; //tells are always echo
message->set_number(static_cast<eqproto::MessageType>(7));
ClientListEntry* cle = client_list.FindCharacter(message->to().c_str());
if (cle == 0 || cle->Online() < CLE_Status_Zoning ||
(cle->TellsOff() && ((cle->Anon() == 1 && message->fromadmin() < cle->Admin()) || message->fromadmin() < 80))) {
message->set_response_error(eqproto::ERR_Failed);
message->set_response_message("Player is offline");
SendChannelMessage(message, reply);
return;
}
if (cle->Online() == CLE_Status_Zoning) {
if (cle->TellQueueFull()) {
message->set_response_error(eqproto::ERR_Failed);
message->set_response_message("Queue is full");
SendChannelMessage(message, reply);
return;
}
//This should succeed in going into a tell queue, since it doesn't return we have to detect above
zoneserver_list.SendChannelMessage(from, message->to().c_str(), channel, message->language(), message->message().c_str());
message->set_response_message("Player is zoning, tell is queued");
SendChannelMessage(message, reply);
return;
}
zoneserver_list.SendChannelMessage(from, message->to().c_str(), channel, message->language(), message->message().c_str());
message->set_response_message("Success");
SendChannelMessage(message, reply);
return;
}
// SendChannelMessage will send a channel message to NATS
void NatsManager::SendChannelMessage(eqproto::ChannelMessage* message, const char* reply) {
if (!connect())
return;
size_t event_size = message->ByteSizeLong();
void *event_buffer = malloc(event_size);
if (!message->SerializeToArray(event_buffer, event_size)) {
Log(Logs::General, Logs::NATS, "global.admin_message.out: failed to serialize message");
return;
}
if (reply) {
s = natsConnection_Publish(conn, reply, event_buffer, event_size);
}
else {
s = natsConnection_Publish(conn, "world.channel_message.out", event_buffer, event_size);
}
if (s != NATS_OK) {
Log(Logs::General, Logs::NATS, "world.channel_message.out failed: %s", nats_GetLastError(&s));
return;
}
if (reply)
Log(Logs::General, Logs::NATS, "world.channel_message.in: %s (%d: %s)", message->message().c_str(), message->response_error(), message->response_message().c_str());
else
Log(Logs::General, Logs::NATS, "world.channel_message.out: %s", message->message().c_str());
}
void NatsManager::Load()
{
if (!connect())
return;
return;
}
+44
View File
@@ -0,0 +1,44 @@
#ifndef NATS_H
#define NATS_H
#include "nats.h"
#include "world_config.h"
#include "../common/global_define.h"
#include "../common/types.h"
#include "../common/timer.h"
#ifndef PROTO_H
#define PROTO_H
#include "../common/message.pb.h"
#endif
#include "../common/servertalk.h"
class NatsManager
{
public:
NatsManager();
~NatsManager();
void Process();
void OnChannelMessage(ServerChannelMessage_Struct * msg);
void OnEmoteMessage(ServerEmoteMessage_Struct * msg);
void SendAdminMessage(std::string adminMessage, const char* reply = nullptr);
void GetChannelMessage(eqproto::ChannelMessage* message, const char* reply = nullptr);
void SendChannelMessage(eqproto::ChannelMessage* message, const char* reply = nullptr);
void GetCommandMessage(eqproto::CommandMessage* message, const char* reply = nullptr);
void SendCommandMessage(eqproto::CommandMessage* message, const char* reply = nullptr);
void Save();
void Load();
protected:
bool connect();
Timer nats_timer;
natsConnection *conn = NULL;
natsStatus s;
natsStatistics *stats = NULL;
natsOptions *opts = NULL;
natsSubscription *channelMessageSub = NULL;
natsSubscription *commandMessageSub = NULL;
natsSubscription *adminMessageSub = NULL;
};
#endif
+5 -1
View File
@@ -83,6 +83,7 @@ union semun {
#include "queryserv.h"
#include "web_interface.h"
#include "console.h"
#include "nats_manager.h"
#include "../common/net/servertalk_server.h"
@@ -102,6 +103,7 @@ bool holdzones = false;
const WorldConfig *Config;
EQEmuLogSys LogSys;
WebInterfaceList web_interface;
NatsManager nats;
void CatchSignal(int sig_num);
void CheckForServerScript(bool force_download = false);
@@ -386,6 +388,7 @@ int main(int argc, char** argv) {
adventure_manager.Load();
adventure_manager.LoadLeaderboardInfo();
nats.Load();
Log(Logs::General, Logs::World_Server, "Purging expired instances");
database.PurgeExpiredInstances();
@@ -412,7 +415,7 @@ int main(int argc, char** argv) {
server_opts.credentials = Config->SharedKey;
server_connection->Listen(server_opts);
Log(Logs::General, Logs::World_Server, "Server (TCP) listener started.");
nats.SendAdminMessage("World server booted up.");
server_connection->OnConnectionIdentified("Zone", [&console](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
LogF(Logs::General, Logs::World_Server, "New Zone Server connection from {2} at {0}:{1}",
connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID());
@@ -563,6 +566,7 @@ int main(int argc, char** argv) {
launcher_list.Process();
LFPGroupList.Process();
adventure_manager.Process();
nats.Process();
if (InterserverTimer.Check()) {
InterserverTimer.Start();
+5
View File
@@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "adventure_manager.h"
#include "ucs.h"
#include "queryserv.h"
#include "nats_manager.h"
extern ClientList client_list;
extern GroupLFPList LFPGroupList;
@@ -45,6 +46,7 @@ extern volatile bool UCSServerAvailable_;
extern AdventureManager adventure_manager;
extern UCSConnection UCSLink;
extern QueryServConnection QSLink;
extern NatsManager nats;
void CatchSignal(int sig_num);
ZoneServer::ZoneServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> connection, EQ::Net::ConsoleServer *console)
@@ -409,6 +411,8 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
if (pack->size < sizeof(ServerChannelMessage_Struct))
break;
ServerChannelMessage_Struct* scm = (ServerChannelMessage_Struct*)pack->pBuffer;
nats.OnChannelMessage(scm);
if (scm->chan_num == 20)
{
UCSLink.SendMessage(scm->from, scm->message);
@@ -506,6 +510,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
}
case ServerOP_EmoteMessage: {
ServerEmoteMessage_Struct* sem = (ServerEmoteMessage_Struct*)pack->pBuffer;
nats.OnEmoteMessage(sem);
zoneserver_list.SendEmoteMessageRaw(sem->to, sem->guilddbid, sem->minstatus, sem->type, sem->message);
break;
}
+4 -2
View File
@@ -62,7 +62,7 @@ SET(zone_sources
lua_raid.cpp
lua_spawn.cpp
lua_spell.cpp
lua_stat_bonuses.cpp
lua_stat_bonuses.cpp
embperl.cpp
embxs.cpp
entity.cpp
@@ -82,6 +82,7 @@ SET(zone_sources
mob.cpp
mob_ai.cpp
mod_functions.cpp
nats_manager.cpp
net.cpp
npc.cpp
npc_ai.cpp
@@ -191,13 +192,14 @@ SET(zone_headers
lua_raid.h
lua_spawn.h
lua_spell.h
lua_stat_bonuses.h
lua_stat_bonuses.h
map.h
masterentity.h
maxskill.h
message.h
merc.h
mob.h
nats_manager.h
net.h
npc.h
npc_ai.h
+7
View File
@@ -27,6 +27,7 @@ Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
#include "client.h"
#include "corpse.h"
#include "groups.h"
#include "nats_manager.h"
#include "mob.h"
#include "queryserv.h"
#include "raids.h"
@@ -35,6 +36,7 @@ Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
#include "zonedb.h"
extern QueryServ* QServ;
extern NatsManager nats;
void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, uint32 duration_override, bool followme, bool sticktarg) {
@@ -922,6 +924,7 @@ void Client::SendAlternateAdvancementStats() {
aps->percentage = m_epp.perAA;
QueuePacket(outapp);
safe_delete(outapp);
nats.OnAlternateAdvancementStats(GetID(), aps);
}
void Client::SendAlternateAdvancementPoints() {
@@ -957,6 +960,7 @@ void Client::SendAlternateAdvancementTimer(int ability, int begin, int end) {
uaaout->end = end;
QueuePacket(outapp);
safe_delete(outapp);
nats.OnAlternateAdvancementAction(GetID(), uaaout);
}
//sends all AA timers.
@@ -976,6 +980,7 @@ void Client::SendAlternateAdvancementTimers() {
uaaout->begin = cur->GetStartTime();
uaaout->end = static_cast<uint32>(time(nullptr));
uaaout->ability = cur->GetType() - pTimerAAStart; // uuaaout->ability is really a shared timer number
nats.OnAlternateAdvancementAction(GetID(), uaaout);
QueuePacket(outapp);
}
@@ -1008,6 +1013,8 @@ void Client::ResetAlternateAdvancementTimers() {
uaaout->ability = cur->GetType() - pTimerAAStart;
r_timers.push_back(cur->GetType());
QueuePacket(outapp);
nats.OnAlternateAdvancementAction(GetID(), uaaout);
}
for(auto &i : r_timers) {
+6 -3
View File
@@ -32,6 +32,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "worldserver.h"
#include "zone.h"
#include "lua_parser.h"
#include "nats_manager.h"
#include "fastmath.h"
#include <assert.h>
@@ -54,6 +55,7 @@ extern FastMath g_Math;
extern EntityList entity_list;
extern Zone* zone;
extern NatsManager nats;
EQEmu::skills::SkillType Mob::AttackAnimation(int Hand, const EQEmu::ItemInstance* weapon, EQEmu::skills::SkillType skillinuse)
{
@@ -1655,7 +1657,7 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, EQEmu::skills::Sk
d->damage = damage;
app.priority = 6;
entity_list.QueueClients(this, &app);
nats.OnDeathEvent(d);
/*
#2: figure out things that affect the player dying and mark them dead
*/
@@ -2234,7 +2236,7 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil
entity_list.QueueClients(killer_mob, app, false);
safe_delete(app);
nats.OnDeathEvent(d);
if (respawn2) {
respawn2->DeathReset(1);
}
@@ -2818,6 +2820,7 @@ void Mob::DamageShield(Mob* attacker, bool spell_ds) {
cds->damage = DS;
entity_list.QueueCloseClients(this, outapp);
safe_delete(outapp);
nats.OnDamageEvent(cds->source, cds);
}
else if (DS > 0 && !spell_ds) {
//we are healing the attacker...
@@ -3751,7 +3754,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
CastToClient()->QueuePacket(outapp);
}
}
nats.OnDamageEvent(a->source, a);
safe_delete(outapp);
}
else {
+6 -4
View File
@@ -54,7 +54,9 @@ extern volatile bool RunLoops;
#include "guild_mgr.h"
#include "quest_parser_collection.h"
#include "queryserv.h"
#include "nats_manager.h"
extern NatsManager nats;
extern QueryServ* QServ;
extern EntityList entity_list;
extern Zone* zone;
@@ -1270,7 +1272,7 @@ void Client::Message(uint32 type, const char* message, ...) {
sm->header[2] = 0x00;
sm->msg_type = type;
memcpy(sm->message, buffer, len+1);
nats.OnSpecialMessageEvent(GetID(), sm);
FastQueuePacket(&app);
safe_delete_array(buffer);
@@ -1301,7 +1303,7 @@ void Client::FilteredMessage(Mob *sender, uint32 type, eqFilterType filter, cons
sm->header[2] = 0x00;
sm->msg_type = type;
memcpy(sm->message, buffer, len + 1);
nats.OnSpecialMessageEvent(GetID(), sm);
FastQueuePacket(&app);
safe_delete_array(buffer);
@@ -1341,7 +1343,7 @@ void Client::QuestJournalledMessage(const char *npcname, const char* message) {
dest = dest + strlen(OutNPCName) + 13;
memcpy(dest, OutMessage, strlen(OutMessage) + 1);
nats.OnSpecialMessageEvent(GetID(), sm);
QueuePacket(app);
safe_delete(app);
@@ -3873,7 +3875,7 @@ void Client::Sacrifice(Client *caster)
d->damage = 0;
app.priority = 6;
entity_list.QueueClients(this, &app);
nats.OnDeathEvent(d);
BuffFadeAll();
UnmemSpellAll();
Group *g = GetGroup();
+25 -2
View File
@@ -59,6 +59,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "water_map.h"
#include "worldserver.h"
#include "zone.h"
#include "nats_manager.h"
#ifdef BOTS
#include "bot.h"
@@ -70,6 +71,8 @@ extern volatile bool is_zone_loaded;
extern WorldServer worldserver;
extern PetitionList petition_list;
extern EntityList entity_list;
extern NatsManager nats;
typedef void (Client::*ClientPacketProc)(const EQApplicationPacket *app);
@@ -1223,6 +1226,7 @@ void Client::Handle_Connect_OP_ZoneComplete(const EQApplicationPacket *app)
auto outapp = new EQApplicationPacket(OP_0x0347, 0);
QueuePacket(outapp);
safe_delete(outapp);
nats.OnZoneCompleteEvent(GetID());
return;
}
@@ -1264,6 +1268,8 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
struct in_addr ghost_addr;
ghost_addr.s_addr = eqs->GetRemoteIP();
nats.SendAdminMessage(StringFormat("Ghosting client: Account ID:%i Name:%s Character:%s IP:%s",
client->AccountID(), client->AccountName(), client->GetName(), inet_ntoa(ghost_addr)));
Log(Logs::General, Logs::Error, "Ghosting client: Account ID:%i Name:%s Character:%s IP:%s",
client->AccountID(), client->AccountName(), client->GetName(), inet_ntoa(ghost_addr));
client->Save();
@@ -1794,6 +1800,8 @@ void Client::Handle_OP_AAAction(const EQApplicationPacket *app)
}
AA_Action* action = (AA_Action*)app->pBuffer;
nats.OnAlternateAdvancementActionRequest(GetID(), action);
if (action->action == aaActionActivate) {//AA Hotkey
Log(Logs::Detail, Logs::AA, "Activating AA %d", action->ability);
ActivateAlternateAdvancementAbility(action->ability, action->target_id);
@@ -2952,7 +2960,7 @@ void Client::Handle_OP_Assist(const EQApplicationPacket *app)
}
}
}
nats.OnEntityEvent(OP_Assist, this->GetID(), eid->entity_id);
FastQueuePacket(&outapp);
return;
}
@@ -4010,6 +4018,7 @@ void Client::Handle_OP_Camp(const EQApplicationPacket *app)
if (IsLFP())
worldserver.StopLFP(CharacterID());
nats.OnEntityEvent(OP_Camp, this->GetID(), 0);
if (GetGM())
{
OnDisconnect(true);
@@ -4235,7 +4244,7 @@ void Client::Handle_OP_ChannelMessage(const EQApplicationPacket *app)
Message(13, "You try to speak but cant move your mouth!");
return;
}
nats.OnChannelMessageEvent(this->GetID(), cm);
ChannelMessageReceived(cm->chan_num, cm->language, cm->skill_in_language, cm->message, cm->targetname);
return;
}
@@ -5197,6 +5206,7 @@ void Client::Handle_OP_Damage(const EQApplicationPacket *app)
CombatDamage_Struct* damage = (CombatDamage_Struct*)app->pBuffer;
//dont send to originator of falling damage packets
entity_list.QueueClients(this, app, (damage->type == DamageTypeFalling));
nats.OnDamageEvent(damage->source, damage);
return;
}
@@ -5945,6 +5955,7 @@ void Client::Handle_OP_GMBecomeNPC(const EQApplicationPacket *app)
if (this->Admin() < minStatusToUseGMCommands) {
Message(13, "Your account has been reported for hacking.");
database.SetHackerFlag(this->account_name, this->name, "/becomenpc");
nats.SendAdminMessage(StringFormat("Hacker %s /becomenpc attempt.", GetCleanName()));
return;
}
if (app->size != sizeof(BecomeNPC_Struct)) {
@@ -5976,6 +5987,7 @@ void Client::Handle_OP_GMDelCorpse(const EQApplicationPacket *app)
if (this->Admin() < commandEditPlayerCorpses) {
Message(13, "Your account has been reported for hacking.");
database.SetHackerFlag(this->account_name, this->name, "/delcorpse");
nats.SendAdminMessage(StringFormat("Hacker %s /delcorpse attempt.", GetCleanName()));
return;
}
GMDelCorpse_Struct* dc = (GMDelCorpse_Struct *)app->pBuffer;
@@ -5997,6 +6009,7 @@ void Client::Handle_OP_GMEmoteZone(const EQApplicationPacket *app)
if (this->Admin() < minStatusToUseGMCommands) {
Message(13, "Your account has been reported for hacking.");
database.SetHackerFlag(this->account_name, this->name, "/emote");
nats.SendAdminMessage(StringFormat("Hacker %s /emote attempt.", GetCleanName()));
return;
}
if (app->size != sizeof(GMEmoteZone_Struct)) {
@@ -6030,6 +6043,7 @@ void Client::Handle_OP_GMFind(const EQApplicationPacket *app)
if (this->Admin() < minStatusToUseGMCommands) {
Message(13, "Your account has been reported for hacking.");
database.SetHackerFlag(this->account_name, this->name, "/find");
nats.SendAdminMessage(StringFormat("Hacker %s /find attempt.", GetCleanName()));
return;
}
if (app->size != sizeof(GMSummon_Struct)) {
@@ -6068,6 +6082,7 @@ void Client::Handle_OP_GMGoto(const EQApplicationPacket *app)
if (this->Admin() < minStatusToUseGMCommands) {
Message(13, "Your account has been reported for hacking.");
database.SetHackerFlag(this->account_name, this->name, "/goto");
nats.SendAdminMessage(StringFormat("Hacker %s /goto attempt.", GetCleanName()));
return;
}
GMSummon_Struct* gmg = (GMSummon_Struct*)app->pBuffer;
@@ -6095,6 +6110,7 @@ void Client::Handle_OP_GMHideMe(const EQApplicationPacket *app)
if (this->Admin() < minStatusToUseGMCommands) {
Message(13, "Your account has been reported for hacking.");
database.SetHackerFlag(this->account_name, this->name, "/hideme");
nats.SendAdminMessage(StringFormat("Hacker %s /hideme attempt.", GetCleanName()));
return;
}
if (app->size != sizeof(SpawnAppearance_Struct)) {
@@ -6115,6 +6131,7 @@ void Client::Handle_OP_GMKick(const EQApplicationPacket *app)
if (this->Admin() < minStatusToKick) {
Message(13, "Your account has been reported for hacking.");
database.SetHackerFlag(this->account_name, this->name, "/kick");
nats.SendAdminMessage(StringFormat("Hacker %s /kick attempt.", GetCleanName()));
return;
}
GMKick_Struct* gmk = (GMKick_Struct *)app->pBuffer;
@@ -6145,6 +6162,7 @@ void Client::Handle_OP_GMKill(const EQApplicationPacket *app)
if (this->Admin() < minStatusToUseGMCommands) {
Message(13, "Your account has been reported for hacking.");
database.SetHackerFlag(this->account_name, this->name, "/kill");
nats.SendAdminMessage(StringFormat("Hacker %s /kill attempt.", GetCleanName()));
return;
}
if (app->size != sizeof(GMKill_Struct)) {
@@ -6197,6 +6215,7 @@ void Client::Handle_OP_GMLastName(const EQApplicationPacket *app)
if (this->Admin() < minStatusToUseGMCommands) {
Message(13, "Your account has been reported for hacking.");
database.SetHackerFlag(client->account_name, client->name, "/lastname");
nats.SendAdminMessage(StringFormat("Hacker %s /lastname attempt.", GetCleanName()));
return;
}
else
@@ -6222,6 +6241,7 @@ void Client::Handle_OP_GMNameChange(const EQApplicationPacket *app)
if (this->Admin() < minStatusToUseGMCommands) {
Message(13, "Your account has been reported for hacking.");
database.SetHackerFlag(this->account_name, this->name, "/name");
nats.SendAdminMessage(StringFormat("Hacker %s /name attempt.", GetCleanName()));
return;
}
Client* client = entity_list.GetClientByName(gmn->oldname);
@@ -6366,6 +6386,7 @@ void Client::Handle_OP_GMToggle(const EQApplicationPacket *app)
if (this->Admin() < minStatusToUseGMCommands) {
Message(13, "Your account has been reported for hacking.");
database.SetHackerFlag(this->account_name, this->name, "/toggle");
nats.SendAdminMessage(StringFormat("Hacker %s /toggle attempt.", GetCleanName()));
return;
}
GMToggle_Struct *ts = (GMToggle_Struct *)app->pBuffer;
@@ -6417,6 +6438,7 @@ void Client::Handle_OP_GMZoneRequest(const EQApplicationPacket *app)
if (this->Admin() < minStatusToBeGM) {
Message(13, "Your account has been reported for hacking.");
database.SetHackerFlag(this->account_name, this->name, "/zone");
nats.SendAdminMessage(StringFormat("Hacker %s /zone attempt.", GetCleanName()));
return;
}
@@ -6465,6 +6487,7 @@ void Client::Handle_OP_GMZoneRequest2(const EQApplicationPacket *app)
if (this->Admin() < minStatusToBeGM) {
Message(13, "Your account has been reported for hacking.");
database.SetHackerFlag(this->account_name, this->name, "/zone");
nats.SendAdminMessage(StringFormat("Hacker %s /zone attempt.", GetCleanName()));
return;
}
if (app->size < sizeof(uint32)) {
+3 -1
View File
@@ -45,6 +45,7 @@
#include "../common/string_util.h"
#include "event_codes.h"
#include "guild_mgr.h"
#include "nats_manager.h"
#include "map.h"
#include "petitions.h"
#include "queryserv.h"
@@ -60,6 +61,7 @@ extern volatile bool is_zone_loaded;
extern WorldServer worldserver;
extern PetitionList petition_list;
extern EntityList entity_list;
extern NatsManager nats;
bool Client::Process() {
bool ret = true;
@@ -2182,7 +2184,7 @@ void Client::ClearHover()
EQApplicationPacket *outapp = MakeBuffsPacket(false);
CastToClient()->FastQueuePacket(&outapp);
}
nats.OnSpawnEvent(OP_ZoneEntry, this->GetID(), &sze->player.spawn);
dead = false;
}
+4
View File
@@ -67,10 +67,12 @@
#include "titles.h"
#include "water_map.h"
#include "worldserver.h"
#include "nats_manager.h"
extern QueryServ* QServ;
extern WorldServer worldserver;
extern TaskManager *taskmanager;
extern NatsManager nats;
void CatchSignal(int sig_num);
@@ -566,6 +568,8 @@ int command_realdispatch(Client *c, const char *message)
QServ->PlayerLogEvent(Player_Log_Issued_Commands, c->CharacterID(), event_desc);
}
nats.SendAdminMessage(StringFormat("%s in %s issued command: %s", c->GetCleanName(), database.GetZoneName(zone->GetZoneID()), message));
if(cur->access >= COMMANDS_LOGGING_MIN_STATUS) {
Log(Logs::General, Logs::Commands, "%s (%s) used command: %s (target=%s)", c->GetName(), c->AccountName(), message, c->GetTarget()?c->GetTarget()->GetName():"NONE");
}
+18
View File
@@ -31,9 +31,11 @@
#include "queryserv.h"
#include "questmgr.h"
#include "zone.h"
#include "nats_manager.h"
extern Zone* zone;
extern QueryServ* QServ;
extern NatsManager nats;
/*
@@ -2882,6 +2884,21 @@ XS(XS__varlink) {
XSRETURN(1);
}
XS(XS__adminmessage); // prototype to pass -Wmissing-prototypes
XS(XS__adminmessage) {
dXSARGS;
if (items == 1)
nats.SendAdminMessage(SvPV_nolen(ST(0)));
else if (items == 2)
nats.SendAdminMessage(SvPV_nolen(ST(0)), (int)SvIV(ST(1)));
else
Perl_croak(aTHX_ "Usage: adminmessage(message [, min_status])");
XSRETURN_EMPTY;
}
XS(XS__CreateInstance);
XS(XS__CreateInstance) {
dXSARGS;
@@ -3766,6 +3783,7 @@ EXTERN_C XS(boot_quest)
newXS(strcpy(buf, "addldonwin"), XS__addldonpoints, file);
newXS(strcpy(buf, "addloot"), XS__addloot, file);
newXS(strcpy(buf, "addskill"), XS__addskill, file);
newXS(strcpy(buf, "adminmessage"), XS__adminmessage, file);
newXS(strcpy(buf, "assigntask"), XS__assigntask, file);
newXS(strcpy(buf, "attack"), XS__attack, file);
newXS(strcpy(buf, "attacknpc"), XS__attacknpc, file);
+1
View File
@@ -216,6 +216,7 @@ public:
return it->second;
return nullptr;
}
Doors *GetDoorsByDoorID(uint32 id);
Doors *GetDoorsByDBID(uint32 id);
void RemoveAllCorpsesByCharID(uint32 charid);
+3
View File
@@ -23,8 +23,10 @@
#include "quest_parser_collection.h"
#include "worldserver.h"
#include "zonedb.h"
#include "nats_manager.h"
extern WorldServer worldserver;
extern NatsManager nats;
// @merth: this needs to be touched up
uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
@@ -626,6 +628,7 @@ void Client::DropItem(int16 slot_id, bool recurse)
invalid_drop = nullptr;
database.SetHackerFlag(this->AccountName(), this->GetCleanName(), "Tried to drop an item on the ground that was nodrop!");
nats.SendAdminMessage(StringFormat("Hacker %s: Tried to drop nodrop item on ground", GetCleanName()));
GetInv().DeleteItem(slot_id);
return;
}
+4
View File
@@ -26,6 +26,7 @@
#include "mob.h"
#include "npc.h"
#include "zonedb.h"
#include "nats_manager.h"
#include "global_loot_manager.h"
#include <iostream>
@@ -35,6 +36,8 @@
#define snprintf _snprintf
#endif
extern NatsManager nats;
// Queries the loottable: adds item & coin to the npc
void ZoneDatabase::AddLootTableToNPC(NPC* npc,uint32 loottable_id, ItemList* itemlist, uint32* copper, uint32* silver, uint32* gold, uint32* plat) {
const LootTable_Struct* lts = nullptr;
@@ -250,6 +253,7 @@ void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 ch
wc = (WearChange_Struct*)outapp->pBuffer;
wc->spawn_id = GetID();
wc->material=0;
nats.OnWearChangeEvent(this->GetID(), wc);
}
item->item_id = item2->ID;
+9
View File
@@ -0,0 +1,9 @@
// lua.hpp
// Lua header files for C++
// <<extern "C">> not supplied automatically because Lua also compiles as C++
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
+9 -2
View File
@@ -22,6 +22,7 @@
#include "qglobals.h"
#include "encounter.h"
#include "lua_encounter.h"
#include "nats_manager.h"
struct Events { };
struct Factions { };
@@ -45,6 +46,7 @@ struct lua_registered_event {
extern std::map<std::string, std::list<lua_registered_event>> lua_encounter_events_registered;
extern std::map<std::string, bool> lua_encounters_loaded;
extern std::map<std::string, Encounter *> lua_encounters;
extern NatsManager nats;
extern void MapOpcodes();
extern void ClearMappedOpcode(EmuOpcode op);
@@ -1320,6 +1322,10 @@ void lua_debug(std::string message, int level) {
Log(static_cast<Logs::DebugLevel>(level), Logs::QuestDebug, message);
}
void lua_adminmessage(std::string message) {
nats.SendAdminMessage(message);
}
void lua_update_zone_header(std::string type, std::string value) {
quest_manager.UpdateZoneHeader(type, value);
}
@@ -1698,8 +1704,9 @@ luabind::scope lua_register_general() {
luabind::def("reloadzonestaticdata", &lua_reloadzonestaticdata),
luabind::def("clock", &lua_clock),
luabind::def("create_npc", &lua_create_npc),
luabind::def("debug", (void(*)(std::string))&lua_debug),
luabind::def("debug", (void(*)(std::string, int))&lua_debug)
luabind::def("debug", (void(*)(std::string))&lua_debug),
luabind::def("debug", (void(*)(std::string, int))&lua_debug),
luabind::def("adminmessage", &lua_adminmessage)
];
}
+63 -58
View File
@@ -12,11 +12,12 @@
#include <vector>
#include <zlib.h>
namespace EQEmu {
uint32 EstimateDeflateBuffer(uint32_t len) {
z_stream zstream;
memset(&zstream, 0, sizeof(zstream));
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.opaque = Z_NULL;
@@ -98,7 +99,7 @@ Map::Map() {
}
Map::~Map() {
if(imp) {
if (imp) {
imp->rm->release();
safe_delete(imp);
}
@@ -109,7 +110,7 @@ float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result) const {
return BEST_Z_INVALID;
glm::vec3 tmp;
if(!result)
if (!result)
result = &tmp;
start.z += RuleI(Map, FindBestZHeightAdjust);
@@ -119,19 +120,19 @@ float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result) const {
bool hit = false;
hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
if(hit) {
if (hit) {
return result->z;
}
// Find nearest Z above us
to.z = -BEST_Z_INVALID;
hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
if (hit)
{
return result->z;
}
return BEST_Z_INVALID;
}
@@ -140,25 +141,25 @@ float Map::FindClosestZ(glm::vec3 &start, glm::vec3 *result) const {
//
if (!imp)
return false;
float ClosestZ = BEST_Z_INVALID;
glm::vec3 tmp;
if (!result)
result = &tmp;
glm::vec3 from(start.x, start.y, start.z);
glm::vec3 to(start.x, start.y, BEST_Z_INVALID);
float hit_distance;
bool hit = false;
// first check is below us
hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
if (hit) {
ClosestZ = result->z;
}
// Find nearest Z above us
to.z = -BEST_Z_INVALID;
hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
@@ -171,7 +172,7 @@ float Map::FindClosestZ(glm::vec3 &start, glm::vec3 *result) const {
}
bool Map::LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const {
if(!imp)
if (!imp)
return false;
return imp->rm->raycast((const RmReal*)&start, (const RmReal*)&end, (RmReal*)result, nullptr, nullptr);
}
@@ -179,7 +180,7 @@ bool Map::LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::ve
bool Map::LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) const {
if (!imp)
return false;
float z = BEST_Z_INVALID;
glm::vec3 step;
glm::vec3 cur;
@@ -213,7 +214,7 @@ bool Map::LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_
//while we are not past end
//always do this once, even if start == end.
while(cur.x != end.x || cur.y != end.y || cur.z != end.z)
while (cur.x != end.x || cur.y != end.y || cur.z != end.z)
{
steps++;
glm::vec3 me;
@@ -232,7 +233,7 @@ bool Map::LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_
return true;
//look at current location
if(LineIntersectsZone(start, end, step_mag, result))
if (LineIntersectsZone(start, end, step_mag, result))
{
return true;
}
@@ -246,13 +247,13 @@ bool Map::LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_
cur.z += step.z;
//watch for end conditions
if ( (cur.x > end.x && end.x >= start.x) || (cur.x < end.x && end.x <= start.x) || (step.x == 0) ) {
if ((cur.x > end.x && end.x >= start.x) || (cur.x < end.x && end.x <= start.x) || (step.x == 0)) {
cur.x = end.x;
}
if ( (cur.y > end.y && end.y >= start.y) || (cur.y < end.y && end.y <= start.y) || (step.y == 0) ) {
if ((cur.y > end.y && end.y >= start.y) || (cur.y < end.y && end.y <= start.y) || (step.y == 0)) {
cur.y = end.y;
}
if ( (cur.z > end.z && end.z >= start.z) || (cur.z < end.z && end.z < start.z) || (step.z == 0) ) {
if ((cur.z > end.z && end.z >= start.z) || (cur.z < end.z && end.z < start.z) || (step.z == 0)) {
cur.z = end.z;
}
}
@@ -262,7 +263,7 @@ bool Map::LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_
}
bool Map::CheckLoS(glm::vec3 myloc, glm::vec3 oloc) const {
if(!imp)
if (!imp)
return false;
return !imp->rm->raycast((const RmReal*)&myloc, (const RmReal*)&oloc, nullptr, nullptr, nullptr);
@@ -270,7 +271,7 @@ bool Map::CheckLoS(glm::vec3 myloc, glm::vec3 oloc) const {
// returns true if a collision happens
bool Map::DoCollisionCheck(glm::vec3 myloc, glm::vec3 oloc, glm::vec3 &outnorm, float &distance) const {
if(!imp)
if (!imp)
return false;
return imp->rm->raycast((const RmReal*)&myloc, (const RmReal*)&oloc, nullptr, (RmReal *)&outnorm, (RmReal *)&distance);
@@ -322,14 +323,14 @@ bool Map::Load(std::string filename)
#endif /*USE_MAP_MMFS*/
FILE *f = fopen(filename.c_str(), "rb");
if(f) {
if (f) {
uint32 version;
if(fread(&version, sizeof(version), 1, f) != 1) {
if (fread(&version, sizeof(version), 1, f) != 1) {
fclose(f);
return false;
}
if(version == 0x01000000) {
if (version == 0x01000000) {
Log(Logs::General, Logs::Status, "Loaded V1 Map File :: '%s'", filename.c_str());
bool v = LoadV1(f);
fclose(f);
@@ -340,7 +341,8 @@ bool Map::Load(std::string filename)
#endif /*USE_MAP_MMFS*/
return v;
} else if(version == 0x02000000) {
}
else if (version == 0x02000000) {
Log(Logs::General, Logs::Status, "Loaded V2 Map File :: '%s'", filename.c_str());
bool v = LoadV2(f);
fclose(f);
@@ -351,12 +353,13 @@ bool Map::Load(std::string filename)
#endif /*USE_MAP_MMFS*/
return v;
} else {
}
else {
fclose(f);
return false;
}
}
return false;
}
@@ -364,39 +367,39 @@ bool Map::LoadV1(FILE *f) {
uint32 face_count;
uint16 node_count;
uint32 facelist_count;
if(fread(&face_count, sizeof(face_count), 1, f) != 1) {
if (fread(&face_count, sizeof(face_count), 1, f) != 1) {
return false;
}
if(fread(&node_count, sizeof(node_count), 1, f) != 1) {
if (fread(&node_count, sizeof(node_count), 1, f) != 1) {
return false;
}
if(fread(&facelist_count, sizeof(facelist_count), 1, f) != 1) {
if (fread(&facelist_count, sizeof(facelist_count), 1, f) != 1) {
return false;
}
std::vector<glm::vec3> verts;
std::vector<uint32> indices;
for(uint32 i = 0; i < face_count; ++i) {
for (uint32 i = 0; i < face_count; ++i) {
glm::vec3 a;
glm::vec3 b;
glm::vec3 c;
float normals[4];
if(fread(&a, sizeof(glm::vec3), 1, f) != 1) {
if (fread(&a, sizeof(glm::vec3), 1, f) != 1) {
return false;
}
if(fread(&b, sizeof(glm::vec3), 1, f) != 1) {
if (fread(&b, sizeof(glm::vec3), 1, f) != 1) {
return false;
}
if(fread(&c, sizeof(glm::vec3), 1, f) != 1) {
if (fread(&c, sizeof(glm::vec3), 1, f) != 1) {
return false;
}
if(fread(normals, sizeof(normals), 1, f) != 1) {
if (fread(normals, sizeof(normals), 1, f) != 1) {
return false;
}
@@ -410,22 +413,23 @@ bool Map::LoadV1(FILE *f) {
verts.push_back(c);
indices.push_back((uint32)sz + 2);
}
if(imp) {
if (imp) {
imp->rm->release();
imp->rm = nullptr;
} else {
}
else {
imp = new impl;
}
imp->rm = createRaycastMesh((RmUint32)verts.size(), (const RmReal*)&verts[0], face_count, &indices[0]);
if(!imp->rm) {
if (!imp->rm) {
delete imp;
imp = nullptr;
return false;
}
return true;
}
@@ -1034,7 +1038,7 @@ bool Map::LoadMMF(const std::string& map_file_name, bool force_mmf_overwrite)
Log(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - f@file_version", mmf_file_name.c_str());
return false;
}
uint32 rm_buffer_size;
if (fread(&rm_buffer_size, sizeof(uint32), 1, f) != 1) {
fclose(f);
@@ -1067,7 +1071,7 @@ bool Map::LoadMMF(const std::string& map_file_name, bool force_mmf_overwrite)
Log(Logs::General, Logs::Zone_Server, "Failed to load Map MMF file: '%s' - f@mmf_buffer", mmf_file_name.c_str());
return false;
}
fclose(f);
std::vector<char> rm_buffer(rm_buffer_size);
@@ -1111,14 +1115,14 @@ bool Map::SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite)
Log(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s'", mmf_file_name.c_str());
return false;
}
FILE* f = fopen(mmf_file_name.c_str(), "rb");
if (f) {
fclose(f);
if (!force_mmf_overwrite)
return true;
}
std::vector<char> rm_buffer; // size set in MyRaycastMesh::serialize()
serializeRaycastMesh(imp->rm, rm_buffer);
if (rm_buffer.empty()) {
@@ -1130,19 +1134,19 @@ bool Map::SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite)
uint32 mmf_buffer_size = EstimateDeflateBuffer(rm_buffer.size());
std::vector<char> mmf_buffer(mmf_buffer_size);
mmf_buffer_size = DeflateData(rm_buffer.data(), rm_buffer.size(), mmf_buffer.data(), mmf_buffer.size());
if (!mmf_buffer_size) {
Log(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - null MMF buffer size", mmf_file_name.c_str());
return false;
}
f = fopen(mmf_file_name.c_str(), "wb");
if (!f) {
Log(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - could not open file", mmf_file_name.c_str());
return false;
}
uint32 file_version = 0;
if (fwrite(&file_version, sizeof(uint32), 1, f) != 1) {
fclose(f);
@@ -1150,7 +1154,7 @@ bool Map::SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite)
Log(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - f@file_version", mmf_file_name.c_str());
return false;
}
if (fwrite(&rm_buffer_size, sizeof(uint32), 1, f) != 1) {
fclose(f);
std::remove(mmf_file_name.c_str());
@@ -1172,7 +1176,7 @@ bool Map::SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite)
Log(Logs::General, Logs::Zone_Server, "Failed to save Map MMF file: '%s' - f@mmf_buffer_size", mmf_file_name.c_str());
return false;
}
if (fwrite(mmf_buffer.data(), mmf_buffer_size, 1, f) != 1) {
fclose(f);
std::remove(mmf_file_name.c_str());
@@ -1181,8 +1185,9 @@ bool Map::SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite)
}
fclose(f);
return true;
}
#endif /*USE_MAP_MMFS*/
}
+28 -27
View File
@@ -30,41 +30,42 @@
#define BEST_Z_INVALID -99999
extern const ZoneConfig *Config;
class Map
namespace EQEmu
{
public:
Map();
~Map();
class Map
{
public:
Map();
~Map();
float FindBestZ(glm::vec3 &start, glm::vec3 *result) const;
float FindClosestZ(glm::vec3 &start, glm::vec3 *result) const;
bool LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const;
bool LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) const;
bool CheckLoS(glm::vec3 myloc, glm::vec3 oloc) const;
bool DoCollisionCheck(glm::vec3 myloc, glm::vec3 oloc, glm::vec3 &outnorm, float &distance) const;
float FindBestZ(glm::vec3 &start, glm::vec3 *result) const;
float FindClosestZ(glm::vec3 &start, glm::vec3 *result) const;
bool LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const;
bool LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) const;
bool CheckLoS(glm::vec3 myloc, glm::vec3 oloc) const;
bool DoCollisionCheck(glm::vec3 myloc, glm::vec3 oloc, glm::vec3 &outnorm, float &distance) const;
#ifdef USE_MAP_MMFS
bool Load(std::string filename, bool force_mmf_overwrite = false);
bool Load(std::string filename, bool force_mmf_overwrite = false);
#else
bool Load(std::string filename);
bool Load(std::string filename);
#endif
static Map *LoadMapFile(std::string file);
private:
void RotateVertex(glm::vec3 &v, float rx, float ry, float rz);
void ScaleVertex(glm::vec3 &v, float sx, float sy, float sz);
void TranslateVertex(glm::vec3 &v, float tx, float ty, float tz);
bool LoadV1(FILE *f);
bool LoadV2(FILE *f);
static Map *LoadMapFile(std::string file);
private:
void RotateVertex(glm::vec3 &v, float rx, float ry, float rz);
void ScaleVertex(glm::vec3 &v, float sx, float sy, float sz);
void TranslateVertex(glm::vec3 &v, float tx, float ty, float tz);
bool LoadV1(FILE *f);
bool LoadV2(FILE *f);
#ifdef USE_MAP_MMFS
bool LoadMMF(const std::string& map_file_name, bool force_mmf_overwrite);
bool SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite);
bool LoadMMF(const std::string& map_file_name, bool force_mmf_overwrite);
bool SaveMMF(const std::string& map_file_name, bool force_mmf_overwrite);
#endif /*USE_MAP_MMFS*/
struct impl;
impl *imp;
};
#endif
struct impl;
impl *imp;
};
}
#endif
+16 -7
View File
@@ -23,6 +23,7 @@
#include "quest_parser_collection.h"
#include "string_ids.h"
#include "worldserver.h"
#include "nats_manager.h"
#include <limits.h>
#include <math.h>
@@ -37,6 +38,7 @@ extern EntityList entity_list;
extern Zone* zone;
extern WorldServer worldserver;
extern NatsManager nats;
Mob::Mob(const char* in_name,
const char* in_lastname,
@@ -946,7 +948,7 @@ void Mob::CreateSpawnPacket(EQApplicationPacket* app, Mob* ForWho) {
memset(app->pBuffer, 0, app->size);
NewSpawn_Struct* ns = (NewSpawn_Struct*)app->pBuffer;
FillSpawnStruct(ns, ForWho);
nats.OnSpawnEvent(OP_NewSpawn, ns->spawn.spawnId, &ns->spawn);
if(RuleB(NPC, UseClassAsLastName) && strlen(ns->spawn.lastName) == 0)
{
switch(ns->spawn.class_)
@@ -1262,6 +1264,7 @@ void Mob::CreateDespawnPacket(EQApplicationPacket* app, bool Decay)
ds->spawn_id = GetID();
// The next field only applies to corpses. If 0, they vanish instantly, otherwise they 'decay'
ds->Decay = Decay ? 1 : 0;
nats.OnDeleteSpawnEvent(this->GetID(), ds);
}
void Mob::CreateHPPacket(EQApplicationPacket* app)
@@ -1272,7 +1275,7 @@ void Mob::CreateHPPacket(EQApplicationPacket* app)
app->pBuffer = new uchar[app->size];
memset(app->pBuffer, 0, sizeof(SpawnHPUpdate_Struct2));
SpawnHPUpdate_Struct2* ds = (SpawnHPUpdate_Struct2*)app->pBuffer;
nats.OnHPEvent(OP_MobHealth, this->GetID(), cur_hp, max_hp);
ds->spawn_id = GetID();
// they don't need to know the real hp
ds->hp = (int)GetHPRatio();
@@ -1306,7 +1309,7 @@ void Mob::CreateHPPacket(EQApplicationPacket* app)
// sends hp update of this mob to people who might care
void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= false*/)
{
nats.OnHPEvent(OP_HPUpdate, this->GetID(), cur_hp, max_hp);
/* If our HP is different from last HP update call - let's update ourself */
if (IsClient()) {
if (cur_hp != last_hp || force_update_all) {
@@ -1469,7 +1472,7 @@ void Mob::SendPosition() {
else {
entity_list.QueueCloseClients(this, app, true, RuleI(Range, MobPositionUpdates), nullptr, false);
}
nats.OnClientUpdateEvent(this->GetID(), spu);
safe_delete(app);
}
@@ -1483,7 +1486,7 @@ void Mob::SendPositionUpdateToClient(Client *client) {
MakeSpawnUpdateNoDelta(spawn_update);
client->QueuePacket(app, false);
nats.OnClientUpdateEvent(this->GetID(), spawn_update);
safe_delete(app);
}
@@ -1506,6 +1509,7 @@ void Mob::SendPositionUpdate(uint8 iSendToSelf) {
else {
entity_list.QueueCloseClients(this, app, (iSendToSelf == 0), RuleI(Range, MobPositionUpdates), nullptr, false);
}
nats.OnClientUpdateEvent(this->GetID(), spu);
safe_delete(app);
}
@@ -1624,7 +1628,7 @@ void Mob::DoAnim(const int animnum, int type, bool ackreq, eqFilterType filter)
ackreq, /* Packet ACK */
filter /* eqFilterType filter */
);
nats.OnAnimationEvent(this->GetID(), anim);
safe_delete(outapp);
}
@@ -2901,7 +2905,7 @@ void Mob::SendWearChange(uint8 material_slot, Client *one_client)
{
one_client->QueuePacket(outapp, false, Client::CLIENT_CONNECTED);
}
nats.OnWearChangeEvent(this->GetID(), wc);
safe_delete(outapp);
}
@@ -2925,6 +2929,7 @@ void Mob::SendTextureWC(uint8 slot, uint16 texture, uint32 hero_forge_model, uin
entity_list.QueueClients(this, outapp);
nats.OnWearChangeEvent(this->GetID(), wc);
safe_delete(outapp);
}
@@ -2947,6 +2952,7 @@ void Mob::SetSlotTint(uint8 material_slot, uint8 red_tint, uint8 green_tint, uin
wc->wear_slot_id = material_slot;
entity_list.QueueClients(this, outapp);
nats.OnWearChangeEvent(this->GetID(), wc);
safe_delete(outapp);
}
@@ -2964,6 +2970,7 @@ void Mob::WearChange(uint8 material_slot, uint16 texture, uint32 color, uint32 h
wc->wear_slot_id = material_slot;
entity_list.QueueClients(this, outapp);
nats.OnWearChangeEvent(this->GetID(), wc);
safe_delete(outapp);
}
@@ -4690,7 +4697,9 @@ void Mob::DoKnockback(Mob *caster, uint32 pushback, uint32 pushup)
outapp_push->priority = 6;
entity_list.QueueClients(this, outapp_push, true);
CastToClient()->FastQueuePacket(&outapp_push);
nats.OnClientUpdateEvent(this->GetID(), spu);
}
}
void Mob::TrySpellOnKill(uint8 level, uint16 spell_id)
File diff suppressed because it is too large Load Diff
+68
View File
@@ -0,0 +1,68 @@
#ifndef _NATS_H
#define _NATS_H
#include "nats.h"
//#include "event_codes.h"
//#include "entity.h"
//#include "mob.h"
#include "../common/opcodemgr.h"
//#include "../common/global_define.h"
//#include "../common/types.h"
#undef New //Needed for MSVC compile
#undef Move //Needed for linux compile
#ifndef PROTO_H
#define PROTO_H
#include "../common/message.pb.h"
#endif
class NatsManager
{
public:
NatsManager();
~NatsManager();
void Process();
void Unregister();
void ZoneSubscribe(const char * zonename, uint32 instance);
void Load();
void GetChannelMessage(eqproto::ChannelMessage* message, const char* reply = nullptr);
void SendChannelMessage(eqproto::ChannelMessage* message, const char* reply = nullptr);
void GetCommandMessage(eqproto::CommandMessage* message, const char* reply = nullptr);
void SendCommandMessage(eqproto::CommandMessage* message, const char* reply = nullptr);
void SendAdminMessage(std::string adminMessage, int min_status = 200);
void SendEvent(eqproto::OpCode op, uint32 entity_id, void * buffer, size_t size);
void OnAlternateAdvancementStats(uint32 entity_id, AltAdvStats_Struct * aas);
void OnAlternateAdvancementAction(uint32 entity_id, UseAA_Struct * uaas);
void OnAlternateAdvancementActionRequest(uint32 entity_id, AA_Action* action);
void OnAnimationEvent(uint32 entity_id, Animation_Struct * anim);
void OnChannelMessageEvent(uint32 entity_id, ChannelMessage_Struct * cm);
void OnClientUpdateEvent(uint32 entity_id, PlayerPositionUpdateServer_Struct * spu);
void OnDamageEvent(uint32 entity_id, CombatDamage_Struct * cd);
void OnDeathEvent(Death_Struct * d);
void OnDeleteSpawnEvent(uint32 entity_id, DeleteSpawn_Struct * ds);
void OnEntityEvent(const EmuOpcode op, uint32 entity_id, uint32 target_id);
void OnHPEvent(const EmuOpcode op, uint32 entity_id, uint32 cur_hp, uint32 max_hp);
void OnSpawnEvent(const EmuOpcode op, uint32 entity_id, Spawn_Struct * spawn);
void OnSpecialMessageEvent(uint32 entity_id, SpecialMesg_Struct *sm);
void OnWearChangeEvent(uint32 entity_id, WearChange_Struct * wc);
void OnZoneCompleteEvent(uint32 entity_id);
void OnNewZoneEvent(uint32 entity_id, NewZone_Struct * nz);
protected:
bool connect();
Timer nats_timer;
bool isEntitySubscribed(const uint16 ID);
bool isEntityEventAllEnabled = true;
natsConnection *conn = NULL;
natsStatus s;
natsOptions *opts = NULL;
std::string subscribedZoneName;
uint32 subscribedZoneInstance;
natsSubscription *zoneChannelMessageSub = NULL;
natsSubscription *zoneInstanceChannelMessageSub = NULL;
natsSubscription *zoneCommandMessageSub = NULL;
natsSubscription *zoneInstanceCommandMessageSub = NULL;
void EncodeEntity(Entity *entity, eqproto::Entity *out);
};
#endif
+13 -3
View File
@@ -62,6 +62,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "embparser.h"
#include "lua_parser.h"
#include "questmgr.h"
#include "nats_manager.h"
#include "../common/event/event_loop.h"
#include "../common/event/timer.h"
@@ -100,6 +101,8 @@ WorldServer worldserver;
uint32 numclients = 0;
char errorname[32];
extern Zone* zone;
NatsManager nats;
npcDecayTimes_Struct npcCorpseDecayTimes[100];
TitleManager title_manager;
QueryServ *QServ = 0;
@@ -131,7 +134,7 @@ int main(int argc, char** argv) {
std::string filename = Config->MapDir;
filename += mapfile;
auto m = new Map();
auto m = new EQEmu::Map();
auto success = m->Load(filename, true);
delete m;
std::cout << mapfile.c_str() << " conversion " << (success ? "succeeded" : "failed") << std::endl;
@@ -148,6 +151,7 @@ int main(int argc, char** argv) {
return 1;
}
Config = ZoneConfig::get();
nats.Load();
const char *zone_name;
uint32 instance_id = 0;
@@ -510,10 +514,14 @@ int main(int argc, char** argv) {
entity_list.MobProcess();
entity_list.BeaconProcess();
entity_list.EncounterProcess();
if (zone->IsLoaded()) {
nats.ZoneSubscribe(zone->GetShortName(), zone->GetInstanceID());
nats.Process();
}
if (zone) {
if (!zone->Process()) {
Zone::Shutdown();
nats.Unregister();
}
}
@@ -571,8 +579,10 @@ int main(int argc, char** argv) {
safe_delete(Config);
if (zone != 0)
if (zone != 0) {
Zone::Shutdown(true);
nats.Unregister();
}
//Fix for Linux world server problem.
safe_delete(taskmanager);
command_deinit();
+5
View File
@@ -30,6 +30,7 @@
#include "quest_parser_collection.h"
#include "string_ids.h"
#include "worldserver.h"
#include "nats_manager.h"
#include <math.h>
@@ -42,6 +43,7 @@
extern Zone* zone;
extern volatile bool is_zone_loaded;
extern WorldServer worldserver;
extern NatsManager nats;
// the spell can still fail here, if the buff can't stack
@@ -936,6 +938,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
Save();
safe_delete(action_packet);
safe_delete(message_packet);
nats.OnDamageEvent(cd->source, cd);
}
else
{
@@ -987,6 +990,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
Save();
safe_delete(action_packet);
safe_delete(message_packet);
nats.OnDamageEvent(cd->source, cd);
}
}
else
@@ -1025,6 +1029,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
Save();
safe_delete(action_packet);
safe_delete(message_packet);
nats.OnDamageEvent(cd->source, cd);
}
}
}
+8 -2
View File
@@ -81,6 +81,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
#include "quest_parser_collection.h"
#include "string_ids.h"
#include "worldserver.h"
#include "nats_manager.h"
#include "fastmath.h"
#include <assert.h>
@@ -105,6 +106,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
extern Zone* zone;
extern volatile bool is_zone_loaded;
extern WorldServer worldserver;
extern NatsManager nats;
extern FastMath g_Math;
using EQEmu::CastingSlot;
@@ -254,6 +256,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
Log(Logs::General, Logs::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) which they shouldn't be able to equip!",
CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID);
database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking equip-only item with an invalid class");
nats.SendAdminMessage(StringFormat("Hacker %s: Clicking equip-only item with an invalid class.", GetCleanName()));
}
else {
Message_StringID(13, MUST_EQUIP_ITEM);
@@ -266,6 +269,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
Log(Logs::General, Logs::Error, "HACKER: %s (account: %s) attempted to click a race/class restricted effect on item %s (id: %d) which they shouldn't be able to click!",
CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID);
database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking race/class restricted item with an invalid class");
nats.SendAdminMessage(StringFormat("Hacker %s: Clicking race/class restricted item with invalid class.", GetCleanName()));
}
else {
if (CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::RoF)
@@ -286,6 +290,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
// They are attempting to cast a must equip clicky without having it equipped
Log(Logs::General, Logs::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) without equiping it!", CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID);
database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking equip-only item without equiping it");
nats.SendAdminMessage(StringFormat("Hacker %s: Clicking equip-only item without equipping it.", GetCleanName()));
}
else {
Message_StringID(13, MUST_EQUIP_ITEM);
@@ -2703,7 +2708,7 @@ void Mob::BardPulse(uint16 spell_id, Mob *caster) {
}
safe_delete(message_packet);
safe_delete(packet);
nats.OnDamageEvent(cd->source, cd);
}
//we are done...
return;
@@ -3995,7 +4000,8 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
);
}
safe_delete(action_packet);
safe_delete(message_packet);
safe_delete(message_packet);
nats.OnDamageEvent(cd->source, cd);
Log(Logs::Detail, Logs::Spells, "Cast of %d by %s on %s complete successfully.", spell_id, GetName(), spelltar->GetName());
+3 -1
View File
@@ -25,7 +25,7 @@
#include "client.h"
#include "entity.h"
#include "mob.h"
#include "nats_manager.h"
#include "quest_parser_collection.h"
#include "string_ids.h"
#include "worldserver.h"
@@ -34,6 +34,7 @@ class QueryServ;
extern WorldServer worldserver;
extern QueryServ* QServ;
extern NatsManager nats;
// The maximum amount of a single bazaar/barter transaction expressed in copper.
// Equivalent to 2 Million plat
@@ -1658,6 +1659,7 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs, Client* Trader, const EQApplic
if(!TakeMoneyFromPP(TotalCost)) {
database.SetHackerFlag(account_name, name, "Attempted to buy something in bazaar but did not have enough money.");
nats.SendAdminMessage(StringFormat("Hacker %s: Attempted to buy something in bazaar but did not have enough money.", GetCleanName()));
TradeRequestFailed(app);
safe_delete(outapp);
return;
+3
View File
@@ -23,8 +23,10 @@
#include "client.h"
#include "entity.h"
#include "mob.h"
#include "nats_manager.h"
#include "trap.h"
extern NatsManager nats;
/*
Schema:
@@ -223,6 +225,7 @@ void Trap::Trigger(Mob* trigger)
a->type = 253;
trigger->CastToClient()->QueuePacket(outapp);
safe_delete(outapp);
nats.OnDamageEvent(a->source, a);
}
}
+1 -1
View File
@@ -896,7 +896,7 @@ bool Zone::Init(bool iStaticZone) {
}
}
zone->zonemap = Map::LoadMapFile(zone->map_name);
zone->zonemap = EQEmu::Map::LoadMapFile(zone->map_name);
zone->watermap = WaterMap::LoadWaterMapfile(zone->map_name);
zone->pathing = PathManager::LoadPathFile(zone->map_name);
+2 -2
View File
@@ -72,7 +72,7 @@ struct item_tick_struct {
};
class Client;
class Map;
//class Map; //Unused? Needed to uncomment for NATS
class Mob;
class PathManager;
class WaterMap;
@@ -212,7 +212,7 @@ public:
void ReloadWorld(uint32 Option);
void ReloadMerchants();
Map* zonemap;
EQEmu::Map* zonemap;
WaterMap* watermap;
PathManager *pathing;
NewZone_Struct newzone_data;