mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-22 20:33:01 +00:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b83fafb745 | |||
| bcc42edb16 | |||
| 0eba5f2990 | |||
| c70bdc6b70 | |||
| 6a25f30441 | |||
| 825dbc9e9a | |||
| a5f35bf32a | |||
| c09ab507dd | |||
| 483ca9996b | |||
| 122f1cd02d | |||
| e0d4f9ecd1 | |||
| cb72ad4d0f | |||
| 98f4e570e7 | |||
| 6532a81b80 | |||
| b0f591540c | |||
| ac07e7d578 | |||
| 40ef387496 | |||
| c9a79af79b | |||
| 1a71237dc2 | |||
| f990292660 | |||
| e72f1e855f | |||
| 3bc9e4bc24 | |||
| 22aef8ad79 | |||
| bf84fcd908 | |||
| 0c5779d2de | |||
| 2270bd267d | |||
| feec425be9 | |||
| dd5ef6523f | |||
| c69b9a95b7 |
+17
-10
@@ -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
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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...")
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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++; }
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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();
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -216,6 +216,7 @@ public:
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Doors *GetDoorsByDoorID(uint32 id);
|
||||
Doors *GetDoorsByDBID(uint32 id);
|
||||
void RemoveAllCorpsesByCharID(uint32 charid);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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();
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user