diff options
author | Hello TMW <hello@themanaworld.org> | 2025-03-12 12:16:19 +0000 |
---|---|---|
committer | Hello TMW <hello@themanaworld.org> | 2025-03-12 12:16:19 +0000 |
commit | b0428330565e92350b002d969c90601f90dc47e5 (patch) | |
tree | 1f22af7cf0039ac80e032edad8876ae0e348867c | |
parent | 3a0bfe045e24a8d769c60b513ade85505926be70 (diff) | |
parent | 88dfbd91ed22ab4ad98b2b9f0243f9d9faa9b49d (diff) | |
download | tmwa-b0428330565e92350b002d969c90601f90dc47e5.tar.gz tmwa-b0428330565e92350b002d969c90601f90dc47e5.tar.bz2 tmwa-b0428330565e92350b002d969c90601f90dc47e5.tar.xz tmwa-b0428330565e92350b002d969c90601f90dc47e5.zip |
-rw-r--r-- | .gitignore | 6 | ||||
-rw-r--r-- | .gitlab-ci.yml | 74 | ||||
-rw-r--r-- | .gitmodules | 2 | ||||
-rw-r--r-- | CMakeLists.txt | 188 | ||||
-rw-r--r-- | COPYING | 2 | ||||
-rw-r--r-- | Makefile.in | 88 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rwxr-xr-x | configure | 10 | ||||
m--------- | deps/attoconf | 0 | ||||
-rw-r--r-- | generate.mk (renamed from generate.make) | 0 | ||||
-rw-r--r-- | src/char/char.cpp | 2 | ||||
-rw-r--r-- | src/conf/install.hpp.in (renamed from src/conf/install.hpp) | 7 | ||||
-rw-r--r-- | src/conf/version.hpp.in (renamed from src/conf/version.hpp) | 21 | ||||
-rw-r--r-- | src/main-gdb-head.py | 2 | ||||
-rw-r--r-- | src/map/clif.cpp | 2 | ||||
-rw-r--r-- | src/map/mob.cpp | 173 | ||||
-rw-r--r-- | src/map/npc-parse.cpp | 7 | ||||
-rw-r--r-- | src/map/script-fun.cpp | 241 | ||||
-rw-r--r-- | src/map/script-parse.py | 2 | ||||
-rw-r--r-- | src/mmo/version.cpp | 2 | ||||
-rw-r--r-- | src/shared/lib.cpp | 2 | ||||
-rwxr-xr-x | tools/bs-align | 2 | ||||
-rwxr-xr-x | tools/colorize | 4 | ||||
-rwxr-xr-x | tools/config.py | 10 | ||||
-rwxr-xr-x | tools/debug-debug-scripts | 9 | ||||
-rw-r--r-- | tools/debug-debug.gdb | 6 | ||||
-rwxr-xr-x | tools/indenter | 7 | ||||
-rwxr-xr-x | tools/pp-indent | 2 | ||||
-rwxr-xr-x | tools/protocol.py | 128 | ||||
-rw-r--r-- | version.mk (renamed from version.make) | 31 |
30 files changed, 649 insertions, 383 deletions
@@ -9,10 +9,12 @@ /src/proto2/ /src/debug-debug/ /src/*/*_conf.[ch]pp +/src/conf/version.hpp # tags file /tags # generated by configure /Makefile +/src/conf/install.hpp /config.status /lib # generated by python @@ -32,3 +34,7 @@ # generic build /build/ + +# CI build +/build-atto/ +/build-cmake/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f7c750a..0368723 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,6 +8,7 @@ variables: &base_vars # Depth of clone. If no tag is made after this many commits, then # the git describe call and version header generation will fail. GIT_DEPTH: 100 # Will break again eventually. + GIT_SUBMODULE_STRATEGY: normal .prerequisites: &prerequisites before_script: @@ -15,21 +16,21 @@ variables: &base_vars - apt-get update - apt-get install -y -qq $INSTALL_PACKAGES $DEBIAN_COMMON_PACKAGES - # Active server OS? -re:ubuntu1804:build: +re:ubuntu1804-attoconf:build: <<: *prerequisites stage: build image: ubuntu:18.04 variables: <<: *base_vars - INSTALL_PACKAGES: python + INSTALL_PACKAGES: python3 script: - echo "Building TMW Athena $CI_BUILD_NAME" - - git submodule update --init - git fetch -t - printf "Building TMW Athena version %s\n" "$(git describe --tags HEAD)" - - ./configure --user + - mkdir build-atto + - cd build-atto + - ../configure --user - make - whoami - make install @@ -37,23 +38,20 @@ re:ubuntu1804:build: untracked: true expire_in: 30 mins - - - # Next server OS? -re:ubuntu2204:build: +re:ubuntu2204-attoconf:build: <<: *prerequisites stage: build image: ubuntu:22.04 variables: <<: *base_vars - INSTALL_PACKAGES: python2 + INSTALL_PACKAGES: python3 script: - - ln -s /usr/bin/python2 /usr/bin/python - - git submodule update --init - git fetch -t - printf "Building TMW Athena version %s\n" "$(git describe --tags HEAD)" - - ./configure --user + - mkdir build-atto + - cd build-atto + - ../configure --user - make - whoami - make install @@ -61,31 +59,69 @@ re:ubuntu2204:build: untracked: true expire_in: 30 mins - +# Next server OS, with cmake +re:ubuntu2204:build: + <<: *prerequisites + stage: build + image: ubuntu:22.04 + variables: + <<: *base_vars + INSTALL_PACKAGES: python3 cmake + script: + - git fetch -t + - printf "Building TMW Athena version %s\n" "$(git describe --tags HEAD)" + - mkdir build-cmake + - cd build-cmake + - cmake -DCMAKE_INSTALL_PREFIX=$HOME/.local .. + - make + - whoami + - make install + artifacts: # required for test stage + untracked: true + expire_in: 30 mins # Disabled. fails with: # (1) GDB failing to resolve a type # (2) /usr/bin/ld: Dwarf Error: Can't find .debug_ranges section. -.re:ubuntu1804:test: +.re:ubuntu1804-attoconf:test: <<: *prerequisites stage: test image: ubuntu:18.04 + needs: ["ubuntu1804-attoconf:build"] + variables: + <<: *base_vars + INSTALL_PACKAGES: python3 gdb + script: + - printf "Testing TMW Athena version %s\n" "$(git describe --tags HEAD)" + - cd build-atto + - make test + + +# Enabled tests +re:ubuntu2204-attoconf:test: + <<: *prerequisites + stage: test + image: ubuntu:22.04 + needs: ["re:ubuntu2204-attoconf:build"] variables: <<: *base_vars - INSTALL_PACKAGES: python gdb + INSTALL_PACKAGES: python3 gdb script: - printf "Testing TMW Athena version %s\n" "$(git describe --tags HEAD)" + - cd build-atto - make test -re:ubuntu2204:test: +# Disabled. Tests are not supported yet by the CMake project. +.re:ubuntu2204:test: <<: *prerequisites stage: test image: ubuntu:22.04 + needs: ["re:ubuntu2204:build"] variables: <<: *base_vars - INSTALL_PACKAGES: python2 gdb + INSTALL_PACKAGES: python3 gdb script: - - ln -s /usr/bin/python2 /usr/bin/python - printf "Testing TMW Athena version %s\n" "$(git describe --tags HEAD)" + - cd build-cmake - make test diff --git a/.gitmodules b/.gitmodules index 8197e60..48c5d1f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "deps/attoconf"] path = deps/attoconf - url = https://github.com/o11c/attoconf.git + url = https://github.com/Freeyorp/attoconf [submodule "deps/googletest"] path = deps/googletest url = https://github.com/google/googletest.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5d550f3 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,188 @@ +cmake_minimum_required(VERSION 3.10) + +# Function for conveniently capturing git output, used to set version related variables +find_package(Git REQUIRED) +function(git_capture_output var) + execute_process(COMMAND ${GIT_EXECUTABLE} ${ARGN} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE ${var} + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + message(STATUS "${var} = ${${var}}") + set(${var} ${${var}} PARENT_SCOPE) +endfunction() + +git_capture_output(VERSION_FULL describe --tags) +git_capture_output(VERSION_HASH rev-parse HEAD) + +# Capture the major.minor.patch part of the version based on the last tag +string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" VERSION ${VERSION_FULL}) + +# Capture the tweak part of the version +if(${VERSION_FULL} MATCHES "^v[0-9]+\\.[0-9]+\\.[0-9]+-([0-9]+)-g[0-9a-f]+$") + set(VERSION "${VERSION}.${CMAKE_MATCH_1}") +else() + set(VERSION "${VERSION}.0") +endif() + +project(tmwAthena VERSION ${VERSION} LANGUAGES CXX) + +# Prefer to use G++ as the compiler +set(CMAKE_CXX_COMPILER g++) +# Set C++ standard to C++11 +# Note we want -std=c++11, not -std=gnu++11, as we want to avoid GNU extensions +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Some sources and includes are generated, such as the protocol headers. +# We defer to generate.make for these rules. +# Note that these are raw Makefile rules, not CMake rules, so a simple +# add_custom_command() won't work. +execute_process(COMMAND make -f ${CMAKE_SOURCE_DIR}/generate.mk + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + +# The generate target must be re-run when the scripts change +set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS + "${PROJECT_SOURCE_DIR}/generate.mk" + "${PROJECT_SOURCE_DIR}/tools/config.py" + "${PROJECT_SOURCE_DIR}/tools/protocol.py" +) + +# Search through the tree for sources +# For each subfolder in src, add all .cpp, .hpp and .tcc files to a subfolder's SOURCES +# variable. +set(ALL_SOURCES "") +foreach(dir admin ast char compat conf generic high ints io login map mmo net proto-base range sexpr shared strings tests wire) + file(GLOB_RECURSE ${dir}_SOURCES CONFIGURE_DEPENDS + src/${dir}/*.cpp + src/${dir}/*.hpp + src/${dir}/*.tcc) + # Exclude any _test.cpp files from the build + set(ALL_SOURCES ${ALL_SOURCES} ${${dir}_SOURCES}) + list(FILTER ${dir}_SOURCES EXCLUDE REGEX ".*_test.cpp") + message("Adding sources in ${dir}: ${${dir}_SOURCES}") +endforeach() + +# All targets include the include/ directory +include_directories(include) + +# We want -fvisibility=hidden for regular objects, but not shared libraries. +# CMake provides a helpful preset for this. +# FIXME this is currently broken +#set(CMAKE_CXX_VISIBILITY_PRESET hidden) +# General purpose build flags. +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -fstack-protector -fno-strict-aliasing -flto=auto") +# Enable link time optimization, and track function and data sections. We let +# the linker remove unused code. +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto=auto -ffunction-sections -fdata-sections -Wl,--gc-sections") +# Next, add warnings +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") +# Add debug information +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb") + +# Vendor Name: String (no newlines, no parentheses) +# This is usually one word, and does not (usually) change over time. +# (Examples: Gentoo, Debian, Fedora, Ubuntu) +set(VENDOR_NAME Vanilla) +# Vendor Point: Integer (max value 65535) +# This is intended to be the "packaging revision number", assuming that's +# an integer. At a minimum, please try to make it nonzero if you have +# any non-upstream patches (unconditionally nonzero is also okay). +# (If your revision 0 package has patches ... please be nicer to upstream) +set(VENDOR_POINT 0) +# URL where the source may be found (after searching for version number). +# See AGPLv3 section 13 +set(VENDOR_SOURCE https://git.themanaworld.org/legacy/tmwa) + +# Convenience +set(VERSION_STRING "TMWA ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} dev${PROJECT_VERSION_TWEAK} +${VENDOR_POINT} (${VENDOR_NAME})") +set(VERSION_DOTS "${PROJECT_VERSION}.${VENDOR_POINT}") + +include(GNUInstallDirs) +set(PACKAGEDATADIR "${CMAKE_INSTALL_FULL_DATAROOTDIR}/tmwa") +set(LOCALSTATEDIR "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}") +set(SYSCONFDIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}") + +# Generate the install.hpp and version.hpp files. +configure_file(src/conf/install.hpp.in src/conf/install.hpp @ONLY) +configure_file(src/conf/version.hpp.in src/conf/version.hpp @ONLY) +set(conf_SOURCES ${conf_SOURCES} src/conf/install.hpp src/conf/version.hpp) +# And have the build search for files in the build directory. +# Note that #includes with generated files should use a path relative to the +# top level source or build directory. +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +# Add a shared library: libtmwa-shared.so.0 +# When we add_executable later, we need to link against this library. +add_library(tmwa-shared SHARED ${shared_SOURCES} + src/io/dir.cpp + src/io/fd.cpp + src/io/read.cpp + src/io/write.cpp + ${strings_SOURCES} +) +# SO versioning +set(ABI_VERSION 0) +set_target_properties(tmwa-shared PROPERTIES + VERSION ${ABI_VERSION}.${VERSION_DOTS} + SOVERSION ${ABI_VERSION}) + +# We have four binaries we want to build: tmwa-{login,char,map,admin} +add_executable(tmwa-login ${login_SOURCES} + ${generic_SOURCES} + ${high_SOURCES} + ${io_SOURCES} + ${mmo_SOURCES} + ${net_SOURCES} + ${wire_SOURCES} +) +target_link_libraries(tmwa-login tmwa-shared) + +add_executable(tmwa-char ${char_SOURCES} + ${generic_SOURCES} + ${high_SOURCES} + ${io_SOURCES} + ${mmo_SOURCES} + ${net_SOURCES} + ${wire_SOURCES} +) +target_link_libraries(tmwa-char tmwa-shared) + +add_executable(tmwa-map ${map_SOURCES} + ${ast_SOURCES} + ${compat_SOURCES} + ${generic_SOURCES} + ${high_SOURCES} + ${io_SOURCES} + ${mmo_SOURCES} + ${net_SOURCES} + ${wire_SOURCES} + ) +target_link_libraries(tmwa-map tmwa-shared) + +add_executable(tmwa-admin ${admin_SOURCES} + ${generic_SOURCES} + ${high_SOURCES} + ${io_SOURCES} + ${mmo_SOURCES} + ${net_SOURCES} + ${wire_SOURCES} +) +target_link_libraries(tmwa-admin tmwa-shared) + +# TODO: Call make -f ${CMAKE_SOURCE_DIR}/generate.mk clean to clean up the +# generated files. We want this to be run every time we call make clean. + +# Install targets +install(TARGETS tmwa-login tmwa-char tmwa-map tmwa-admin tmwa-shared + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} +) + +# Install shared configuration and data +install(FILES etc/tmwa/shared.conf DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/tmwa) +install(FILES share/tmwa/shared.data DESTINATION ${CMAKE_INSTALL_DATADIR}/tmwa) + +# Make sure there is a var directory +install(DIRECTORY DESTINATION ${CMAKE_INSTALL_LOCALSTATEDIR}/tmwa) @@ -5,7 +5,7 @@ This combination is explicitly allowed by section 13 of the licenses. See gpl-3.0.txt or agpl-3.0.txt for specific terms. In order to make life easy for users who run this software publicly, -please set VENDOR_SOURCE in version.make if you make any modifications. +please set VENDOR_SOURCE in version.mk if you make any modifications. History: diff --git a/Makefile.in b/Makefile.in index 10f909c..075c107 100644 --- a/Makefile.in +++ b/Makefile.in @@ -152,7 +152,7 @@ $(info The Road goes ever on and on ...) endif endif -include ${SRC_DIR}/version.make +include ${SRC_DIR}/version.mk ifeq (${ENABLE_SHARED},yes) LIB_SUFFIX_FAKE := so @@ -184,12 +184,13 @@ export PATH:=$(realpath ${SRC_DIR}/tools):${PATH} SHELL=bash # need to generate source files before path lists -$(shell make -f ${SRC_DIR}/generate.make >&2) +$(shell make -f ${SRC_DIR}/generate.mk >&2) stamp/generated.stamp: # if you get here, the shell above failed false # path lists +GENERATED_FILES := src/conf/version.hpp REAL_SOURCES := $(shell cd ${SRC_DIR}; find src/ -name '*.cpp') REAL_HEADERS := $(shell cd ${SRC_DIR}; find include/ src/ -name '*.hpp' -o -name '*.tcc') PIES := $(shell cd ${SRC_DIR}; find src/ -name '*.py') @@ -283,9 +284,9 @@ endif # This needs to edit CXX instead of CXXFLAGS in order to make # the %.ii rule work. ifeq (${ENABLE_CYGWIN_HACKS},yes) -override CXX += -std=gnu++0x +override CXX += -std=gnu++11 else -override CXX += -std=c++0x +override CXX += -std=c++11 endif CXXFLAGS += -fstack-protector @@ -333,9 +334,60 @@ include ${DEPENDS} endif thisdir := $(abspath .) + #$(foreach root,${PATTERN_ROOTS},$(info pre-root: ${root} := $(value ${root}))$(info )) # can't do $(filter %.hpp yet) -$(foreach root,${PATTERN_ROOTS},$(eval ${root} := $(sort $(patsubst ${thisdir}/%,%,$(abspath $(patsubst ${SRC_DIR}/%,%,$(wildcard $(value ${root})) $(filter conf-raw/%.h,$(value ${root})))))))) + +# Sanitize the dependencies. +# +# ${root} has a value like "mmo/version", and ${mmo/version} in turn has the +# value of all of its dependencies (from the %.d files). +# +# This reassigns the *value of the value* of ${root} to be: +# - sorted +# - relative and simplified: it's stripped of any absolute path relative to +# the current directory after being converted to an absolute path. +# This also converts paths from being relative to the build directory to +# being relative to the source directory, if they differ. +# This simplifies any construct such as: +# ../src/mmo/../strings/zstring.tcc +# to: +# src/strings/zstring.tcc +# - only files which either exist (the purpose of the wildcard function), +# are in the conf-raw directory (the first filter function), or +# are listed in the GENERATED_FILES variable (the second filter function). +# This means that if there are any build-time generated files added, this +# needs to be modified to not filter them out. +# +# The end result for each root will look something like: +# mmo/version := conf-raw/int-VENDOR_POINT.h conf-raw/int-VERSION_DEVEL.h [...] +# src/strings/zstring.tcc src/wire/fwd.hpp + +# Firstly, make the paths relative and simplified. +$(foreach root,${PATTERN_ROOTS},$(eval \ + ${root} := $(sort $(patsubst ${thisdir}/%,%, \ + $(abspath $(patsubst ${SRC_DIR}/%,%, $(value ${root}))) \ + )) \ +)) + +# Secondly, make sure that the files actually exist, or are files we expect to +# generate ourselves. Sort the result for readability. +# Note that we re-add and remove the ${SRC_DIR} prefix when first testing for +# existence, as we need to test for existence relative to our build directory. +# The second wildcard test doesn't add a ${SRC_DIR} prefix, but does strip it, +# handling the case where the file is specified relative to the source +# directory (mostly the case in test sources). +$(foreach root,${PATTERN_ROOTS},$(eval \ + ${root} := $(sort \ + $(patsubst ${SRC_DIR}/%,%,$(wildcard $(addprefix ${SRC_DIR}/, \ + $(value ${root}) \ + ))) \ + $(patsubst ${SRC_DIR}/%,%,$(wildcard ${SRC_DIR})) \ + $(filter conf-raw/%.h,$(value ${root})) \ + $(filter ${GENERATED_FILES},$(value ${root})) \ + ) \ +)) + # have to redo what we undid to get it as a variable $(foreach root,${PATTERN_ROOTS},$(eval obj/${root}.ii obj/${root}.ll obj/${root}.bc obj/${root}.s obj/${root}.pdc.o obj/${root}.pic.o obj/${root}.d : $(value ${root})) ) #$(foreach root,${PATTERN_ROOTS},$(info post-root: ${root} := $(value ${root}))$(info )) @@ -386,6 +438,7 @@ vpath include/%.hpp ${SRC_DIR} vpath src/%.tcc ${SRC_DIR} vpath tools/% ${SRC_DIR} vpath src/%.py ${SRC_DIR} +vpath src/%.in ${SRC_DIR} .DELETE_ON_ERROR: .DEFAULT_GOAL := all @@ -437,6 +490,10 @@ obj/%.d: src/%.cpp | stamp/generated.stamp ${CXX} ${CPPFLAGS} -DGENERATING_DEPENDENCIES ${CXXFLAGS} -MG -MM \ -MT '$(patsubst obj/%.d,%,$@) := ' \ -MF $@ $< +# -MG takes the include parameter as-is without prepending the path whenever +# it's not found, and presumed to be a not-yet generated file. +# #include statements for generated files should always be relative to the +# source (or build) directory. endif # the above SRC_DIR replacement is not really safe, but it works okayish. obj/%.ii: src/%.cpp @@ -508,8 +565,8 @@ obj/gtest%.pdc.o: ${GTEST_DIR}/src/gtest%.cc DTEST_OBJS := $(filter obj/debug-debug/%.pdc.o,${PDC_OBJECTS}) DTEST_STAMPS := $(patsubst bin/tests/%.elf,stamp/run-%.stamp,${DTEST_BINARIES}) -${DTEST_OBJS}: override CXXFLAGS += -g -O0 -gdwarf-3 -${DTEST_STAMPS}: override TESTER=${GDB} -return-child-result -nx -batch -ex 'python file_to_load = "$<"' -x ${SRC_DIR}/tools/debug-debug.gdb --args false +${DTEST_OBJS}: override CXXFLAGS += -ggdb -O0 +${DTEST_STAMPS}: override TESTER=LD_LIBRARY_PATH="./lib" ${GDB} -return-child-result -nx -batch -ex 'python file_to_load = "$<"' -x ${SRC_DIR}/tools/debug-debug.gdb --args false ${DTEST_STAMPS}: tools/debug-debug.gdb test: test-direct @@ -539,7 +596,7 @@ test: test-rank-fwd test-rank-fwd: ${CHECK_RANK_FWDS} stamp/%.rank: src/% $(MKDIR_FIRST) - includes=$$(grep '#include.*".*/.*"' $< | sed 's/^[^"]*"//;s/"[^"]*$$//;s:/[^/]*$$::' | sort -u | fgrep -vx -e '..' -e 'conf-raw' -e '../conf'); \ + includes=$$(grep '#include.*".*/.*"' $< | sed 's/^[^"]*"//;s/"[^"]*$$//;s:/[^/]*$$::' | sort -u | fgrep -vx -e '..' -e 'conf-raw' -e '../conf' -e 'src/conf'); \ for inc in $$includes; do if ! test -f ${<D}/fwd.hpp; then continue; fi; echo fgrep -q $${inc}/fwd.hpp ${<D}/fwd.hpp; fgrep -q $${inc}/fwd.hpp ${<D}/fwd.hpp || { echo ${<D}/fwd.hpp:''23: error: No $${inc}/fwd.hpp; exit 1; }; done touch $@ @@ -682,21 +739,22 @@ conf-raw/bool-%.h: FORCE conf-raw/str-%.h: FORCE $(MKDIR_FIRST) @echo '#define $* "$(value $*)"_s' | maybe-replace $@ -FORCE: ; + +FORCE:: ; .PHONY: FORCE -override CPPFLAGS += -I . -I ${SRC_DIR}/include +override CPPFLAGS += -I. -I${SRC_DIR} -I${SRC_DIR}/include # distribution tarballs # this only works from within a git checkout -dist/%/version.make: +dist/%/version.mk: $(MKDIR_FIRST) - git --git-dir=${SRC_DIR}/.git show HEAD:version.make > $@ + git --git-dir=${SRC_DIR}/.git show HEAD:version.mk > $@ sed 's/^VERSION_FULL := .*/#&\nVERSION_FULL := ${VERSION_FULL}/' -i $@ sed 's/^VERSION_HASH := .*/#&\nVERSION_HASH := ${VERSION_HASH}/' -i $@ -dist/%-src.tar: dist/%/version.make +dist/%-src.tar: dist/%/version.mk git --git-dir=${SRC_DIR}/.git archive --prefix=$*/ -o $@ HEAD - ( mtime="$$(git --git-dir=${SRC_DIR}/.git log -n1 --pretty=%ci)" && cd dist && tar uf $*-src.tar --mtime="$${mtime}" --mode=664 --owner=root --group=root $*/version.make ) - rm dist/$*/version.make + ( mtime="$$(git --git-dir=${SRC_DIR}/.git log -n1 --pretty=%ci)" && cd dist && tar uf $*-src.tar --mtime="$${mtime}" --mode=664 --owner=root --group=root $*/version.mk ) + rm dist/$*/version.mk rmdir dist/$*/ dist/%-attoconf-only.tar: $(MKDIR_FIRST) @@ -11,7 +11,7 @@ The rest of this file contains information relevant to distributors and contribu ## 1. Distributors ### Important notes -- Please read [version.make](version.make) for important version information. +- Please read [version.mk](version.mk) for important version information. - TMWA requires git to build by default. Use 'make dist' to get a tarball. ### Platform dependencies @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2013 Ben Longbons <b.r.longbons@gmail.com> # @@ -17,8 +17,6 @@ # You should have received a copy of the GNU General Public License # along with attoconf. If not, see <http://www.gnu.org/licenses/>. -from __future__ import print_function, division, absolute_import - import os import sys @@ -90,7 +88,7 @@ class Configuration(Cxx, Install, ConfigHash, Templates): # 2) Modern distros ship gtest-1.13+. It requires C++14+, while # TMWA is currently a C++0x codebase. self.add_option('GTEST_DIR', - init=os.path.join(os.getcwd(), 'deps/googletest/googletest'), + init=os.path.join(os.path.abspath(self.srcdir), 'deps/googletest/googletest'), # http://code.google.com/p/googletest/wiki/FAQ#Why_is_it_not_recommended_to_install_a_pre-compiled_copy_of_Goog type=filepath, check=lambda build, GTEST_DIR: None, help='Location of Google Test sources, must contain src/gtest-all.cc (linking to a precompiled library is NOT supported)', hidden=False) @@ -112,7 +110,9 @@ def main(): srcdir = os.path.dirname(sys.argv[0]) proj = Configuration( srcdir=srcdir, - template_files=['Makefile'], + # Note that src/conf/version.hpp is made later, by Makefile. + # See version.mk (included by Makefile). + template_files=['Makefile', 'src/conf/install.hpp'], ) proj.set_package('tmwa', 'The Mana World (Athena server)'); proj.jiggle() diff --git a/deps/attoconf b/deps/attoconf -Subproject 7b939e7e4ce36e8b62b10025e567f871731cbf4 +Subproject 58e75e5f1271363a48c2a3417a2851d3b145b3f diff --git a/generate.make b/generate.mk index c32ca8d..c32ca8d 100644 --- a/generate.make +++ b/generate.mk diff --git a/src/char/char.cpp b/src/char/char.cpp index 7ffdd0f..2194ef2 100644 --- a/src/char/char.cpp +++ b/src/char/char.cpp @@ -777,8 +777,8 @@ void create_online_files(void) stamp_time(timetemp); // write heading FPRINTF(fp2, "<HTML>\n"_fmt); - FPRINTF(fp2, " <META http-equiv=\"Refresh\" content=\"%d\">\n"_fmt, char_conf.online_refresh_html); // update on client explorer every x seconds FPRINTF(fp2, " <HEAD>\n"_fmt); + FPRINTF(fp2, " <META http-equiv=\"refresh\" content=\"%d\">\n"_fmt, char_conf.online_refresh_html); // update on client explorer every x seconds FPRINTF(fp2, " <TITLE>Online Players on %s</TITLE>\n"_fmt, char_conf.server_name); FPRINTF(fp2, " </HEAD>\n"_fmt); diff --git a/src/conf/install.hpp b/src/conf/install.hpp.in index 42fd125..e63164a 100644 --- a/src/conf/install.hpp +++ b/src/conf/install.hpp.in @@ -20,10 +20,9 @@ // just mention "fwd.hpp" to make formatter happy -#include "conf-raw/str-PACKAGESYSCONFDIR.h" -#include "conf-raw/str-PACKAGELOCALSTATEDIR.h" -#include "conf-raw/str-PACKAGEDATADIR.h" - +#define PACKAGESYSCONFDIR "@SYSCONFDIR@/tmwa"_s +#define PACKAGELOCALSTATEDIR "@LOCALSTATEDIR@/tmwa"_s +#define PACKAGEDATADIR "@PACKAGEDATADIR@"_s namespace tmwa { diff --git a/src/conf/version.hpp b/src/conf/version.hpp.in index df8a8b6..126fae2 100644 --- a/src/conf/version.hpp +++ b/src/conf/version.hpp.in @@ -20,20 +20,19 @@ // just mention "fwd.hpp" to make formatter happy -#include "conf-raw/str-VERSION_FULL.h" -#include "conf-raw/str-VERSION_HASH.h" +#define VERSION_FULL "@VERSION_FULL@"_s +#define VERSION_HASH "@VERSION_HASH@"_s -#include "conf-raw/int-VERSION_MAJOR.h" -#include "conf-raw/int-VERSION_MINOR.h" -#include "conf-raw/int-VERSION_PATCH.h" -#include "conf-raw/int-VERSION_DEVEL.h" +#define VERSION_MAJOR @PROJECT_VERSION_MAJOR@ +#define VERSION_MINOR @PROJECT_VERSION_MINOR@ +#define VERSION_PATCH @PROJECT_VERSION_PATCH@ +#define VERSION_DEVEL @PROJECT_VERSION_TWEAK@ -#include "conf-raw/str-VENDOR_NAME.h" -#include "conf-raw/int-VENDOR_POINT.h" -#include "conf-raw/str-VENDOR_SOURCE.h" - -#include "conf-raw/str-VERSION_STRING.h" +#define VENDOR_NAME "@VENDOR_NAME@"_s +#define VENDOR_POINT @VENDOR_POINT@ +#define VENDOR_SOURCE "@VENDOR_SOURCE@"_s +#define VERSION_STRING "@VERSION_STRING@"_s namespace tmwa { diff --git a/src/main-gdb-head.py b/src/main-gdb-head.py index a465c97..09e22fe 100644 --- a/src/main-gdb-head.py +++ b/src/main-gdb-head.py @@ -5,7 +5,7 @@ # gdb sticks everything in one scope. # This lets us enumerate what *we* added. -initial_globals = {id(v):v for v in globals().values()} +initial_globals = {id(v):v for v in list(globals().values())} import re diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 4d36f17..1b77be6 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -4020,7 +4020,7 @@ RecvResult clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> dumb_ptr<mob_data> md = bl->is_mob(); nullpo_retr(rv, md); - if (md->name != MobName() && md->name != get_mob_db(md->mob_class).name && md->name.size() >= 4) + if (md->name.size() >= 4) fixed_95.char_name = stringish<CharName>(md->name); else fixed_95.char_name = stringish<CharName>(get_mob_db(md->mob_class).name); diff --git a/src/map/mob.cpp b/src/map/mob.cpp index 996e2bb..fc41d19 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -355,24 +355,25 @@ void mob_init(dumb_ptr<mob_data> md) { int i; const Species mob_class = md->mob_class; - const int mutations_nr = get_mob_db(mob_class).mutations_nr; - const int mutation_power = get_mob_db(mob_class).mutation_power; - - md->stats[mob_stat::LV] = get_mob_db(mob_class).lv; - md->stats[mob_stat::MAX_HP] = get_mob_db(mob_class).max_hp; - md->stats[mob_stat::STR] = get_mob_db(mob_class).attrs[ATTR::STR]; - md->stats[mob_stat::AGI] = get_mob_db(mob_class).attrs[ATTR::AGI]; - md->stats[mob_stat::VIT] = get_mob_db(mob_class).attrs[ATTR::VIT]; - md->stats[mob_stat::INT] = get_mob_db(mob_class).attrs[ATTR::INT]; - md->stats[mob_stat::DEX] = get_mob_db(mob_class).attrs[ATTR::DEX]; - md->stats[mob_stat::LUK] = get_mob_db(mob_class).attrs[ATTR::LUK]; - md->stats[mob_stat::ATK1] = get_mob_db(mob_class).atk1; - md->stats[mob_stat::ATK2] = get_mob_db(mob_class).atk2; - md->stats[mob_stat::ADELAY] = get_mob_db(mob_class).adelay.count(); - md->stats[mob_stat::DEF] = get_mob_db(mob_class).def; - md->stats[mob_stat::MDEF] = get_mob_db(mob_class).mdef; - md->stats[mob_stat::CRITICAL_DEF] = get_mob_db(mob_class).critical_def; - md->stats[mob_stat::SPEED] = get_mob_db(mob_class).speed.count(); + const mob_db_& mob_info = get_mob_db(mob_class); + const int mutations_nr = mob_info.mutations_nr; + const int mutation_power = mob_info.mutation_power; + + md->stats[mob_stat::LV] = mob_info.lv; + md->stats[mob_stat::MAX_HP] = mob_info.max_hp; + md->stats[mob_stat::STR] = mob_info.attrs[ATTR::STR]; + md->stats[mob_stat::AGI] = mob_info.attrs[ATTR::AGI]; + md->stats[mob_stat::VIT] = mob_info.attrs[ATTR::VIT]; + md->stats[mob_stat::INT] = mob_info.attrs[ATTR::INT]; + md->stats[mob_stat::DEX] = mob_info.attrs[ATTR::DEX]; + md->stats[mob_stat::LUK] = mob_info.attrs[ATTR::LUK]; + md->stats[mob_stat::ATK1] = mob_info.atk1; + md->stats[mob_stat::ATK2] = mob_info.atk2; + md->stats[mob_stat::ADELAY] = mob_info.adelay.count(); + md->stats[mob_stat::DEF] = mob_info.def; + md->stats[mob_stat::MDEF] = mob_info.mdef; + md->stats[mob_stat::CRITICAL_DEF] = mob_info.critical_def; + md->stats[mob_stat::SPEED] = mob_info.speed.count(); md->stats[mob_stat::XP_BONUS] = MOB_XP_BONUS_BASE; for (i = 0; i < mutations_nr; i++) @@ -2596,6 +2597,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, ); { + const mob_db_& mob_info = get_mob_db(md->mob_class); struct DmgLogParty { PartyPair p; @@ -2660,23 +2662,23 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, per = 1; base_exp = - ((get_mob_db(md->mob_class).base_exp * + ((mob_info.base_exp * md->stats[mob_stat::XP_BONUS]) >> MOB_XP_BONUS_SHIFT) * per / 256; if (base_exp < 1) base_exp = 1; - if (sd && md && battle_config.pk_mode == 1 - && (get_mob_db(md->mob_class).lv - sd->status.base_level >= 20)) + if (sd && battle_config.pk_mode == 1 + && (mob_info.lv - sd->status.base_level >= 20)) { base_exp *= 1.15; // pk_mode additional exp if monster >20 levels [Valaris] } if (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1) base_exp = 0; // Added [Valaris] - job_exp = get_mob_db(md->mob_class).job_exp * per / 256; + job_exp = mob_info.job_exp * per / 256; if (job_exp < 1) job_exp = 1; - if (sd && md && battle_config.pk_mode == 1 - && (get_mob_db(md->mob_class).lv - sd->status.base_level >= 20)) + if (sd && battle_config.pk_mode == 1 + && (mob_info.lv - sd->status.base_level >= 20)) { job_exp *= 1.15; // pk_mode additional exp if monster >20 levels [Valaris] } @@ -2730,13 +2732,14 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, if (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1) // Added [Valaris] break; // End - if (!get_mob_db(md->mob_class).dropitem[i].nameid) + const auto& drop_info = mob_info.dropitem[i]; + if (!drop_info.nameid) continue; - random_::Fixed<int, 10000> drop_rate = get_mob_db(md->mob_class).dropitem[i].p; - if (battle_config.drops_by_luk > 0 && sd && md) + random_::Fixed<int, 10000> drop_rate = drop_info.p; + if (sd && battle_config.drops_by_luk > 0) drop_rate.num += (sd->status.attrs[ATTR::LUK] * battle_config.drops_by_luk) / 100; // drops affected by luk [Valaris] - if (sd && md && battle_config.pk_mode == 1 - && (get_mob_db(md->mob_class).lv - sd->status.base_level >= 20)) + if (sd && battle_config.pk_mode == 1 + && (mob_info.lv - sd->status.base_level >= 20)) drop_rate.num *= 1.25; // pk_mode increase drops if 20 level difference [Valaris] // server-wide drop rate scaling @@ -2745,7 +2748,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, continue; struct delay_item_drop ditem {}; - ditem.nameid = get_mob_db(md->mob_class).dropitem[i].nameid; + ditem.nameid = drop_info.nameid; ditem.amount = 1; ditem.m = md->bl_m; ditem.x = md->bl_x; @@ -2796,9 +2799,11 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage, npc_event(sd, md->npc_event, 0); // TODO: in the future, OnPCKillEvent, OnMobKillEvent and OnPCDieEvent should be combined - argrec_t arg[1] = + argrec_t arg[3] = { {"@mobID"_s, static_cast<int32_t>(unwrap<Species>(md->mob_class))}, + {"@mobX"_s, static_cast<int32_t>(md->bl_x)}, + {"@mobY"_s, static_cast<int32_t>(md->bl_y)}, }; npc_event_doall_l(stringish<ScriptLabel>("OnMobKillEvent"_s), sd->bl_id, arg); } @@ -3501,40 +3506,39 @@ int mobskill_event(dumb_ptr<mob_data> md, BF flag) static int mob_makedummymobdb(Species mob_class) { - int i; - - SNPRINTF(get_mob_db(mob_class).name, 24, "mob%d"_fmt, mob_class); - SNPRINTF(get_mob_db(mob_class).jname, 24, "mob%d"_fmt, mob_class); - get_mob_db(mob_class).lv = 1; - get_mob_db(mob_class).max_hp = 1000; - get_mob_db(mob_class).max_sp = 1; - get_mob_db(mob_class).base_exp = 2; - get_mob_db(mob_class).job_exp = 1; - get_mob_db(mob_class).range = 1; - get_mob_db(mob_class).atk1 = 7; - get_mob_db(mob_class).atk2 = 10; - get_mob_db(mob_class).def = 0; - get_mob_db(mob_class).mdef = 0; - get_mob_db(mob_class).attrs[ATTR::STR] = 1; - get_mob_db(mob_class).attrs[ATTR::AGI] = 1; - get_mob_db(mob_class).attrs[ATTR::VIT] = 1; - get_mob_db(mob_class).attrs[ATTR::INT] = 1; - get_mob_db(mob_class).attrs[ATTR::DEX] = 6; - get_mob_db(mob_class).attrs[ATTR::LUK] = 2; - get_mob_db(mob_class).range2 = 10; - get_mob_db(mob_class).range3 = 10; - get_mob_db(mob_class).size = 0; // 1 - get_mob_db(mob_class).race = Race::formless; - get_mob_db(mob_class).element = LevelElement{0, Element::neutral}; - get_mob_db(mob_class).mode = MobMode::ZERO; - get_mob_db(mob_class).speed = 300_ms; - get_mob_db(mob_class).adelay = 1000_ms; - get_mob_db(mob_class).amotion = 500_ms; - get_mob_db(mob_class).dmotion = 500_ms; - for (i = 0; i < MaxDrops; i++) - { - get_mob_db(mob_class).dropitem[i].nameid = ItemNameId(); - get_mob_db(mob_class).dropitem[i].p.num = 0; + mob_db_& mob_info = get_mob_db(mob_class); + SNPRINTF(mob_info.name, 24, "mob%d"_fmt, mob_class); + SNPRINTF(mob_info.jname, 24, "mob%d"_fmt, mob_class); + mob_info.lv = 1; + mob_info.max_hp = 1000; + mob_info.max_sp = 1; + mob_info.base_exp = 2; + mob_info.job_exp = 1; + mob_info.range = 1; + mob_info.atk1 = 7; + mob_info.atk2 = 10; + mob_info.def = 0; + mob_info.mdef = 0; + mob_info.attrs[ATTR::STR] = 1; + mob_info.attrs[ATTR::AGI] = 1; + mob_info.attrs[ATTR::VIT] = 1; + mob_info.attrs[ATTR::INT] = 1; + mob_info.attrs[ATTR::DEX] = 6; + mob_info.attrs[ATTR::LUK] = 2; + mob_info.range2 = 10; + mob_info.range3 = 10; + mob_info.size = 0; // 1 + mob_info.race = Race::formless; + mob_info.element = LevelElement{0, Element::neutral}; + mob_info.mode = MobMode::ZERO; + mob_info.speed = 300_ms; + mob_info.adelay = 1000_ms; + mob_info.amotion = 500_ms; + mob_info.dmotion = 500_ms; + for (int i = 0; i < MaxDrops; i++) + { + mob_info.dropitem[i].nameid = ItemNameId(); + mob_info.dropitem[i].p.num = 0; } return 0; } @@ -3654,56 +3658,55 @@ bool mob_readdb(ZString filename) continue; } - if (get_mob_db(mob_class).base_exp < 0) + if (mdbv.base_exp < 0) { PRINTF("bad mob line: Xp needs to be greater than 0. %s\n"_fmt, line); rv = false; continue; } - if (get_mob_db(mob_class).base_exp > 1000000000) + if (mdbv.base_exp > 1000000000) { PRINTF("bad mob line: Xp needs to be less than 1000000000. %s\n"_fmt, line); rv = false; continue; } - if (get_mob_db(mob_class).job_exp < 0) + if (mdbv.job_exp < 0) { PRINTF("bad mob line: Job Xp needs to be greater than 0. %s\n"_fmt, line); rv = false; continue; } - if (get_mob_db(mob_class).job_exp > 1000000000) + if (mdbv.job_exp > 1000000000) { PRINTF("bad mob line: Job Xp needs to be less than 1000000000. %s\n"_fmt, line); rv = false; continue; } - // TODO move this lower - get_mob_db(mob_class) = std::move(mdbv); - for (int i = 0; i < MaxDrops; i++) { - int rate = get_mob_db(mob_class).dropitem[i].p.num; + int rate = mdbv.dropitem[i].p.num; if (rate < 1) rate = 1; if (rate > 10000) rate = 10000; - get_mob_db(mob_class).dropitem[i].p.num = rate; + mdbv.dropitem[i].p.num = rate; } - get_mob_db(mob_class).skills.clear(); + mdbv.skills.clear(); + + mdbv.hair = 0; + mdbv.hair_color = 0; + mdbv.weapon = 0; + mdbv.shield = ItemNameId(); + mdbv.head_top = ItemNameId(); + mdbv.head_mid = ItemNameId(); + mdbv.head_buttom = ItemNameId(); + mdbv.clothes_color = 0; //Add for player monster dye - Valaris - get_mob_db(mob_class).hair = 0; - get_mob_db(mob_class).hair_color = 0; - get_mob_db(mob_class).weapon = 0; - get_mob_db(mob_class).shield = ItemNameId(); - get_mob_db(mob_class).head_top = ItemNameId(); - get_mob_db(mob_class).head_mid = ItemNameId(); - get_mob_db(mob_class).head_buttom = ItemNameId(); - get_mob_db(mob_class).clothes_color = 0; //Add for player monster dye - Valaris + if (mdbv.base_exp == 0) + mdbv.base_exp = mob_gen_exp(&mdbv); - if (get_mob_db(mob_class).base_exp == 0) - get_mob_db(mob_class).base_exp = mob_gen_exp(&get_mob_db(mob_class)); + get_mob_db(mob_class) = std::move(mdbv); } PRINTF("read %s done\n"_fmt, filename); } diff --git a/src/map/npc-parse.cpp b/src/map/npc-parse.cpp index df1a09a..8865ea6 100644 --- a/src/map/npc-parse.cpp +++ b/src/map/npc-parse.cpp @@ -273,15 +273,16 @@ bool npc_load_monster(ast::npc::Monster& monster) md->bl_m = m; md->bl_x = x; md->bl_y = y; - MobName expected = get_mob_db(mob_class).jname; + const mob_db_& mob_info = get_mob_db(mob_class); + MobName expected = mob_info.jname; if (monster.name.data != expected) { monster.name.span.warning(STRPRINTF("Visible label/jname should match: %s"_fmt, expected)); } if (monster.name.data == ENGLISH_NAME) - md->name = get_mob_db(mob_class).name; + md->name = mob_info.name; else if (monster.name.data == JAPANESE_NAME) - md->name = get_mob_db(mob_class).jname; + md->name = mob_info.jname; else md->name = monster.name.data; diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index fee39d6..c471da1 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -2683,6 +2683,22 @@ void builtin_getexp(ScriptState *st) *------------------------------------------ */ static +int get_mob_drop_nameid(Species mob_id, int index) +{ + return unwrap<ItemNameId>(get_mob_db(mob_id).dropitem[index].nameid); +} +static +int get_mob_drop_percent(Species mob_id, int index) +{ + return get_mob_db(mob_id).dropitem[index].p.num; +} +static +AString get_mob_drop_name(Species mob_id, int index) +{ + Option<P<struct item_data>> i_data = Some(itemdb_search(get_mob_db(mob_id).dropitem[index].nameid)); + return i_data.pmd_pget(&item_data::name).copy_or(stringish<ItemName>(""_s)); +} +static void builtin_mobinfo(ScriptState *st) { Species mob_id = wrap<Species>(conv_num(st, &AARG(0))); @@ -2697,6 +2713,19 @@ void builtin_mobinfo(ScriptState *st) return; } +#define CASE_MobInfo_DROPID(index) \ + MobInfo::DROPID##index: info = get_mob_drop_nameid(mob_id, index) + +#define CASE_MobInfo_DROPPERCENT(index) \ + MobInfo::DROPPERCENT##index: info = get_mob_drop_percent(mob_id, index) + +#define CASE_MobInfo_DROPNAME(index) \ + MobInfo::DROPNAME##index: \ + { \ + info_str = get_mob_drop_name(mob_id, index); \ + mode = 1; \ + } + switch (request) { case MobInfo::ID: @@ -2800,142 +2829,57 @@ void builtin_mobinfo(ScriptState *st) case MobInfo::MUTATION_POWER: info = get_mob_db(mob_id).mutation_power; break; - case MobInfo::DROPID0: - info = unwrap<ItemNameId>(get_mob_db(mob_id).dropitem[0].nameid); - break; - case MobInfo::DROPNAME0: - { - Option<P<struct item_data>> i_data = Some(itemdb_search(get_mob_db(mob_id).dropitem[0].nameid)); - info_str = i_data.pmd_pget(&item_data::name).copy_or(stringish<ItemName>(""_s)); - mode = 1; - } - break; - case MobInfo::DROPPERCENT0: - info = get_mob_db(mob_id).dropitem[0].p.num; - break; - case MobInfo::DROPID1: - info = unwrap<ItemNameId>(get_mob_db(mob_id).dropitem[0].nameid); - break; - case MobInfo::DROPNAME1: - { - Option<P<struct item_data>> i_data = Some(itemdb_search(get_mob_db(mob_id).dropitem[0].nameid)); - info_str = i_data.pmd_pget(&item_data::name).copy_or(stringish<ItemName>(""_s)); - mode = 1; - } - break; - case MobInfo::DROPPERCENT1: - info = get_mob_db(mob_id).dropitem[0].p.num; - break; - case MobInfo::DROPID2: - info = unwrap<ItemNameId>(get_mob_db(mob_id).dropitem[1].nameid); - break; - case MobInfo::DROPNAME2: - { - Option<P<struct item_data>> i_data = Some(itemdb_search(get_mob_db(mob_id).dropitem[1].nameid)); - info_str = i_data.pmd_pget(&item_data::name).copy_or(stringish<ItemName>(""_s)); - mode = 1; - } - break; - case MobInfo::DROPPERCENT2: - info = get_mob_db(mob_id).dropitem[1].p.num; - break; - case MobInfo::DROPID3: - info = unwrap<ItemNameId>(get_mob_db(mob_id).dropitem[2].nameid); - break; - case MobInfo::DROPNAME3: - { - Option<P<struct item_data>> i_data = Some(itemdb_search(get_mob_db(mob_id).dropitem[2].nameid)); - info_str = i_data.pmd_pget(&item_data::name).copy_or(stringish<ItemName>(""_s)); - mode = 1; - } - break; - case MobInfo::DROPPERCENT3: - info = get_mob_db(mob_id).dropitem[2].p.num; - break; - case MobInfo::DROPID4: - info = unwrap<ItemNameId>(get_mob_db(mob_id).dropitem[3].nameid); - break; - case MobInfo::DROPNAME4: - { - Option<P<struct item_data>> i_data = Some(itemdb_search(get_mob_db(mob_id).dropitem[3].nameid)); - info_str = i_data.pmd_pget(&item_data::name).copy_or(stringish<ItemName>(""_s)); - mode = 1; - } - break; - case MobInfo::DROPPERCENT4: - info = get_mob_db(mob_id).dropitem[3].p.num; - break; - case MobInfo::DROPID5: - info = unwrap<ItemNameId>(get_mob_db(mob_id).dropitem[4].nameid); - break; - case MobInfo::DROPNAME5: - { - Option<P<struct item_data>> i_data = Some(itemdb_search(get_mob_db(mob_id).dropitem[4].nameid)); - info_str = i_data.pmd_pget(&item_data::name).copy_or(stringish<ItemName>(""_s)); - mode = 1; - } - break; - case MobInfo::DROPPERCENT5: - info = get_mob_db(mob_id).dropitem[4].p.num; - break; - case MobInfo::DROPID6: - info = unwrap<ItemNameId>(get_mob_db(mob_id).dropitem[5].nameid); - break; - case MobInfo::DROPNAME6: - { - Option<P<struct item_data>> i_data = Some(itemdb_search(get_mob_db(mob_id).dropitem[5].nameid)); - info_str = i_data.pmd_pget(&item_data::name).copy_or(stringish<ItemName>(""_s)); - mode = 1; - } - break; - case MobInfo::DROPPERCENT6: - info = get_mob_db(mob_id).dropitem[5].p.num; - break; - case MobInfo::DROPID7: - info = unwrap<ItemNameId>(get_mob_db(mob_id).dropitem[6].nameid); - break; - case MobInfo::DROPNAME7: - { - Option<P<struct item_data>> i_data = Some(itemdb_search(get_mob_db(mob_id).dropitem[6].nameid)); - info_str = i_data.pmd_pget(&item_data::name).copy_or(stringish<ItemName>(""_s)); - mode = 1; - } - break; - case MobInfo::DROPPERCENT7: - info = get_mob_db(mob_id).dropitem[6].p.num; - break; - case MobInfo::DROPID8: - info = unwrap<ItemNameId>(get_mob_db(mob_id).dropitem[7].nameid); - break; - case MobInfo::DROPNAME8: - { - Option<P<struct item_data>> i_data = Some(itemdb_search(get_mob_db(mob_id).dropitem[7].nameid)); - info_str = i_data.pmd_pget(&item_data::name).copy_or(stringish<ItemName>(""_s)); - mode = 1; - } - break; - case MobInfo::DROPPERCENT8: - info = get_mob_db(mob_id).dropitem[7].p.num; - break; - case MobInfo::DROPID9: - info = unwrap<ItemNameId>(get_mob_db(mob_id).dropitem[7].nameid); - break; - case MobInfo::DROPNAME9: - { - Option<P<struct item_data>> i_data = Some(itemdb_search(get_mob_db(mob_id).dropitem[7].nameid)); - info_str = i_data.pmd_pget(&item_data::name).copy_or(stringish<ItemName>(""_s)); - mode = 1; - } - break; - case MobInfo::DROPPERCENT9: - info = get_mob_db(mob_id).dropitem[7].p.num; - break; + + case CASE_MobInfo_DROPID(0); break; + case CASE_MobInfo_DROPNAME(0); break; + case CASE_MobInfo_DROPPERCENT(0); break; + + case CASE_MobInfo_DROPID(1); break; + case CASE_MobInfo_DROPNAME(1); break; + case CASE_MobInfo_DROPPERCENT(1); break; + + case CASE_MobInfo_DROPID(2); break; + case CASE_MobInfo_DROPNAME(2); break; + case CASE_MobInfo_DROPPERCENT(2); break; + + case CASE_MobInfo_DROPID(3); break; + case CASE_MobInfo_DROPNAME(3); break; + case CASE_MobInfo_DROPPERCENT(3); break; + + case CASE_MobInfo_DROPID(4); break; + case CASE_MobInfo_DROPNAME(4); break; + case CASE_MobInfo_DROPPERCENT(4); break; + + case CASE_MobInfo_DROPID(5); break; + case CASE_MobInfo_DROPNAME(5); break; + case CASE_MobInfo_DROPPERCENT(5); break; + + case CASE_MobInfo_DROPID(6); break; + case CASE_MobInfo_DROPNAME(6); break; + case CASE_MobInfo_DROPPERCENT(6); break; + + case CASE_MobInfo_DROPID(7); break; + case CASE_MobInfo_DROPNAME(7); break; + case CASE_MobInfo_DROPPERCENT(7); break; + + case CASE_MobInfo_DROPID(8); break; + case CASE_MobInfo_DROPNAME(8); break; + case CASE_MobInfo_DROPPERCENT(8); break; + + case CASE_MobInfo_DROPID(9); break; + case CASE_MobInfo_DROPNAME(9); break; + case CASE_MobInfo_DROPPERCENT(9); break; + default: PRINTF("builtin_mobinfo: unknown request\n"_fmt); push_int<ScriptDataInt>(st->stack, -1); return; break; } +#undef CASE_MobInfo_DROPID +#undef CASE_MobInfo_DROPPERCENT +#undef CASE_MobInfo_DROPNAME + if (!mode) push_int<ScriptDataInt>(st->stack, info); else @@ -3022,7 +2966,9 @@ void builtin_mobinfo_droparrays(ScriptState *st) } for (int i = 0; i < MaxDrops; ++i) - if (get_mob_db(mob_id).dropitem[i].nameid) + { + auto& dropitem = get_mob_db(mob_id).dropitem[i]; + if (dropitem.nameid) { status = 1; switch (request) @@ -3030,15 +2976,15 @@ void builtin_mobinfo_droparrays(ScriptState *st) case MobInfo_DropArrays::IDS: if (name.startswith(".@"_s)) { - struct script_data vd = script_data(ScriptDataInt{unwrap<ItemNameId>(get_mob_db(mob_id).dropitem[i].nameid)}); + struct script_data vd = script_data(ScriptDataInt{unwrap<ItemNameId>(dropitem.nameid)}); set_scope_reg(st, reg.iplus(i), &vd); } else - set_reg(bl, VariableCode::VARIABLE, reg.iplus(i), unwrap<ItemNameId>(get_mob_db(mob_id).dropitem[i].nameid)); + set_reg(bl, VariableCode::VARIABLE, reg.iplus(i), unwrap<ItemNameId>(dropitem.nameid)); break; case MobInfo_DropArrays::NAMES: { - Option<P<struct item_data>> i_data = Some(itemdb_search(get_mob_db(mob_id).dropitem[i].nameid)); + Option<P<struct item_data>> i_data = Some(itemdb_search(dropitem.nameid)); RString item_name = i_data.pmd_pget(&item_data::name).copy_or(stringish<ItemName>(""_s)); if (name.startswith(".@"_s)) @@ -3053,11 +2999,11 @@ void builtin_mobinfo_droparrays(ScriptState *st) case MobInfo_DropArrays::PERCENTS: if (name.startswith(".@"_s)) { - struct script_data vd = script_data(ScriptDataInt{get_mob_db(mob_id).dropitem[i].p.num}); + struct script_data vd = script_data(ScriptDataInt{dropitem.p.num}); set_scope_reg(st, reg.iplus(i), &vd); } else - set_reg(bl, VariableCode::VARIABLE, reg.iplus(i), get_mob_db(mob_id).dropitem[i].p.num); + set_reg(bl, VariableCode::VARIABLE, reg.iplus(i), dropitem.p.num); break; } } @@ -3067,7 +3013,7 @@ void builtin_mobinfo_droparrays(ScriptState *st) status = 2; break; } - + } push_int<ScriptDataInt>(st->stack, status); } @@ -3097,16 +3043,19 @@ void builtin_getmobdrops(ScriptState *st) status = 1; + const mob_db_& mob_info = get_mob_db(mob_id); for (; i < MaxDrops; ++i) - if (get_mob_db(mob_id).dropitem[i].nameid) + { + auto& dropitem = mob_info.dropitem[i]; + if (dropitem.nameid) { - set_reg(bl, VariableCode::VARIABLE, SIR::from(variable_names.intern("$@MobDrop_item"_s), i), get_mob_db(mob_id).dropitem[i].p.num); + set_reg(bl, VariableCode::VARIABLE, SIR::from(variable_names.intern("$@MobDrop_item"_s), i), dropitem.p.num); - Option<P<struct item_data>> i_data = Some(itemdb_search(get_mob_db(mob_id).dropitem[i].nameid)); + Option<P<struct item_data>> i_data = Some(itemdb_search(dropitem.nameid)); RString item_name = i_data.pmd_pget(&item_data::name).copy_or(stringish<ItemName>(""_s)); set_reg(bl, VariableCode::VARIABLE, SIR::from(variable_names.intern("$@MobDrop_name$"_s), i), item_name); - set_reg(bl, VariableCode::VARIABLE, SIR::from(variable_names.intern("$@MobDrop_rate"_s), i), get_mob_db(mob_id).dropitem[i].p.num); + set_reg(bl, VariableCode::VARIABLE, SIR::from(variable_names.intern("$@MobDrop_rate"_s), i), dropitem.p.num); } else { @@ -3114,6 +3063,7 @@ void builtin_getmobdrops(ScriptState *st) status = 2; break; } + } if (status == 1) set_reg(bl, VariableCode::VARIABLE, SIR::from(variable_names.intern("$@MobDrop_count"_s), 0), i); @@ -4366,9 +4316,14 @@ void builtin_getitemlink(ScriptState *st) struct script_data *data; AString buf; data = &AARG(0); - ZString name = conv_str(st, data); + Option<P<struct item_data>> item_data_ = None; + + get_val(st, data); + if (data->is<ScriptDataStr>()) + item_data_ = itemdb_searchname(conv_str(st, data)); + else + item_data_ = itemdb_exists(wrap<ItemNameId>(conv_num(st, data))); - Option<P<struct item_data>> item_data_ = itemdb_searchname(name); OMATCH_BEGIN (item_data_) { OMATCH_CASE_SOME (item_data) diff --git a/src/map/script-parse.py b/src/map/script-parse.py index 199e348..3346b92 100644 --- a/src/map/script-parse.py +++ b/src/map/script-parse.py @@ -106,7 +106,7 @@ class ScriptBuffer(object): code_begin = code['_M_impl']['_M_start'] code_end = code['_M_impl']['_M_finish'] code_size = int(code_end - code_begin) - r = iter(range(code_size)) + r = iter(list(range(code_size))) for i in r: buf = [] for label in labels_dict.get(i, []): diff --git a/src/mmo/version.cpp b/src/mmo/version.cpp index f91b748..c75c25c 100644 --- a/src/mmo/version.cpp +++ b/src/mmo/version.cpp @@ -20,7 +20,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include "../conf/version.hpp" +#include "src/conf/version.hpp" #include "../strings/xstring.hpp" diff --git a/src/shared/lib.cpp b/src/shared/lib.cpp index c0a4371..37b2e93 100644 --- a/src/shared/lib.cpp +++ b/src/shared/lib.cpp @@ -18,7 +18,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. -#include "../conf/install.hpp" +#include "src/conf/install.hpp" #include "../strings/literal.hpp" #include "../strings/astring.hpp" diff --git a/tools/bs-align b/tools/bs-align index 6582298..0caf649 100755 --- a/tools/bs-align +++ b/tools/bs-align @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- encoding: utf-8 ## bs-align.py - Filter to align trailing line continuations ## diff --git a/tools/colorize b/tools/colorize index ce6f410..205a1bc 100755 --- a/tools/colorize +++ b/tools/colorize @@ -1,6 +1,4 @@ -#!/usr/bin/env python - -from __future__ import print_function +#!/usr/bin/env python3 import os import sys diff --git a/tools/config.py b/tools/config.py index f87fe77..22ece0b 100755 --- a/tools/config.py +++ b/tools/config.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # coding: utf-8 # config.py - generator for config file parsers @@ -20,8 +20,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -from __future__ import print_function - import glob import os @@ -259,7 +257,7 @@ class Group(object): short_cpp_name = '%s.cpp' % var_name cpp_name = os.path.join(path, short_cpp_name) - values = sorted(self.options.values(), key=lambda o: o.name) + values = sorted(list(self.options.values()), key=lambda o: o.name) desc = 'Config for %s::%s' % (namespace_name, self.name) with OpenWrite(hpp_name) as hpp, \ @@ -384,7 +382,7 @@ class Realm(object): return rv def dump(self): - for g in self.groups.values(): + for g in list(self.groups.values()): g.dump_in(self.path, self.path.split('/')[-1]) class Everything(object): @@ -401,7 +399,7 @@ class Everything(object): def dump(self): for g in glob.glob('src/*/*_conf.[ch]pp'): os.rename(g, g + '.old') - for v in self.realms.values(): + for v in list(self.realms.values()): v.dump() for g in glob.glob('src/*/*_conf.[ch]pp.old'): print('Obsolete: %s' % g) diff --git a/tools/debug-debug-scripts b/tools/debug-debug-scripts index 2112a6e..5ba7ecb 100755 --- a/tools/debug-debug-scripts +++ b/tools/debug-debug-scripts @@ -1,6 +1,5 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # encoding: utf-8 -from __future__ import print_function copyright = ''' // Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> @@ -35,6 +34,12 @@ error = False def eprint(s): print('Error:', s, file=sys.stderr) +# Implement an equivalent to Python 2's execfile for Python 3 +def execfile(filename, globals=None, locals=None): + with open(filename, 'r') as f: + code = compile(f.read(), filename, 'exec') + exec(code, globals, locals) + def get_classes_from_file(a): global error d = {} diff --git a/tools/debug-debug.gdb b/tools/debug-debug.gdb index b50a49b..5bf3a57 100644 --- a/tools/debug-debug.gdb +++ b/tools/debug-debug.gdb @@ -9,7 +9,7 @@ gdb.execute('file %s' % file_to_load) end set logging file /dev/null set logging redirect on -set logging off +set logging enabled off python import re @@ -41,7 +41,7 @@ set print elements 9999 set print frame-arguments none set python print-stack full -set logging on +set logging enabled on # Workaround "Function... not defined in.." (breakpoints not found) (GDB bug) # https://sourceware.org/bugzilla/show_bug.cgi?id=15962 # In some gdb versions rbreak works, in some break does. @@ -55,7 +55,7 @@ if bpoint.pending: gdb.execute("rbreak do_breakpoint") end -set logging off +set logging enabled off commands silent diff --git a/tools/indenter b/tools/indenter index 0d93543..ee000da 100755 --- a/tools/indenter +++ b/tools/indenter @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- encoding: utf-8 ## indenter.py - Top-level indenter for all files ## @@ -20,10 +20,9 @@ ## along with this program. If not, see <http://www.gnu.org/licenses/>. -from __future__ import print_function from collections import namedtuple -import cStringIO +import io import string import subprocess import sys @@ -114,7 +113,7 @@ class Reader(object): self._column += 1 def string_reader(s, name='<string>', line=1, column=1): - return Reader(name, cStringIO.StringIO(s), line, column) + return Reader(name, io.StringIO(s), line, column) def take_while(b, r, s): assert isinstance(b, bytearray) diff --git a/tools/pp-indent b/tools/pp-indent index 9be9a03..622614a 100755 --- a/tools/pp-indent +++ b/tools/pp-indent @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- encoding: utf-8 ## pp-indent - Filter to apply indentation to preprocessor statements ## diff --git a/tools/protocol.py b/tools/protocol.py index cf89a16..d278884 100755 --- a/tools/protocol.py +++ b/tools/protocol.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # coding: utf-8 # protocol.py - generator for entire TMWA network protocol @@ -20,20 +20,12 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -from __future__ import print_function - import glob -import itertools import os -from pipes import quote +from shlex import quote from posixpath import relpath from weakref import ref as wr -try: - unicode -except NameError: - unicode = str - ## For various reasons this is all one file, so let's navigate with a ## ## Table of Contents @@ -91,7 +83,7 @@ class OpenWrite(object): self.filename = filename def __enter__(self): - self.handle = open(self.filename + '.tmp', 'w') + self.handle = open(self.filename + '.tmp', 'w', encoding='utf-8') return self.handle def __exit__(self, ty, v, tb): @@ -116,30 +108,30 @@ class OpenWrite(object): # TOC_ def gvq(s): - return u'"%s"' % s.replace(u'"', u'\\"') + return '"%s"' % s.replace('"', '\\"') def gva(d): if d: - return u' [%s]' % u', '.join(u'%s=%s' % (ak, gvq(av)) for (ak, av) in sorted(d.items())) - return u'' + return ' [%s]' % ', '.join('%s=%s' % (ak, gvq(av)) for (ak, av) in sorted(d.items())) + return '' class Attributes(object): - __slots__ = (u'_attributes') + __slots__ = ('_attributes') def __init__(self): self._attributes = {} def __getitem__(self, k): - assert isinstance(k, unicode) + assert isinstance(k, str) return self._attributes[k] def __setitem__(self, k, v): - assert isinstance(k, unicode) - assert isinstance(v, unicode) + assert isinstance(k, str) + assert isinstance(v, str) self._attributes[k] = v def __delitem__(self, k): - assert isinstance(k, unicode) + assert isinstance(k, str) del self._attributes[k] def merge(self, *others): @@ -150,7 +142,7 @@ class Attributes(object): self._attributes.update(other._attributes) class Graph(Attributes): - __slots__ = (u'default_vertex', u'default_edge', u'_vertices', u'_edges', u'_vertex_lookup') + __slots__ = ('default_vertex', 'default_edge', '_vertices', '_edges', '_vertex_lookup') def __init__(self): Attributes.__init__(self) @@ -161,7 +153,7 @@ class Graph(Attributes): self._vertex_lookup = {} def vertex(self, name, insert=True): - assert isinstance(name, unicode) + assert isinstance(name, str) vert = self._vertex_lookup.get(name) if insert and vert is None: vert = Vertex(name) @@ -238,21 +230,21 @@ class Graph(Attributes): def p(*args): for x in args: - out.write(unicode(x)) - out.write(u'\n') - p(u'digraph') - p(u'{') + out.write(str(x)) + out.write('\n') + p('digraph') + p('{') for ak, av in sorted(self._attributes.items()): - p(u' ', ak, u'=', gvq(av), u';') + p(' ', ak, '=', gvq(av), ';') for ak, av in sorted(self.default_vertex._attributes.items()): - p(u' node [', ak, u'=', gvq(av), u'];') + p(' node [', ak, '=', gvq(av), '];') for ak, av in sorted(self.default_edge._attributes.items()): - p(u' edge [', ak, u'=', gvq(av), u'];') + p(' edge [', ak, '=', gvq(av), '];') for n in sorted(self._vertices): - p(u' ', n) + p(' ', n) for _, e in sorted(self._edges.items()): - p(u' ', e) - p(u'}') + p(' ', e) + p('}') def dot_str(self): from io import StringIO @@ -261,18 +253,18 @@ class Graph(Attributes): return out.getvalue() def dot_file(self, name): - with open(name, u'w') as f: + with open(name, 'w') as f: self.dot(f, False) def preview(self, block): from subprocess import Popen, PIPE - proc = Popen([u'dot', u'-Txlib', u'/dev/stdin'], stdin=PIPE, universal_newlines=True) + proc = Popen(['dot', '-Txlib', '/dev/stdin'], stdin=PIPE, universal_newlines=True) self.dot(proc.stdin, True) if block: proc.wait() class Vertex(Attributes): - __slots__ = (u'_key', u'_post', u'_pre', u'__weakref__') + __slots__ = ('_key', '_post', '_pre', '__weakref__') def __init__(self, key): Attributes.__init__(self) @@ -281,13 +273,13 @@ class Vertex(Attributes): self._pre = set() def __str__(self): - return u'%s%s;' % (gvq(self._key), gva(self._attributes)) + return '%s%s;' % (gvq(self._key), gva(self._attributes)) def __lt__(self, other): return self._key < other._key class Edge(Attributes): - __slots__ = (u'_from', u'_to') + __slots__ = ('_from', '_to') def __init__(self, f, t): Attributes.__init__(self) @@ -295,7 +287,7 @@ class Edge(Attributes): self._to = t def __str__(self): - return u'%s -> %s%s;' % (gvq(self._from._key), gvq(self._to._key), gva(self._attributes)) + return '%s -> %s%s;' % (gvq(self._from._key), gvq(self._to._key), gva(self._attributes)) # TOC_TYPES @@ -7091,7 +7083,7 @@ def partition(d): changed = True while changed: changed = False - for k, vlist in d.items(): + for k, vlist in list(d.items()): if vlist: m = min(leaders[v] for v in vlist) if m < leaders[k]: @@ -7107,9 +7099,9 @@ def partition(d): leaders[v] = m followers = {} - for k, v in leaders.items(): + for k, v in list(leaders.items()): followers.setdefault(v, []).append(k) - return [set(v) for v in followers.values()] + return [set(v) for v in list(followers.values())] def ids_only(vpost): rv = [e for e in vpost if not isinstance(e, SpecialEventOrigin)] @@ -7124,7 +7116,7 @@ def make_dots(ctx): #p = partition({k: ids_only(v.post) for (k, v) in d.items()}) if not os.path.exists('doc-gen'): - # generate.make will succeed if missing the wiki repo + # generate.mk will succeed if missing the wiki repo # but 'make doc' will fail return for g in glob.glob('doc-gen/*.gv'): @@ -7132,7 +7124,7 @@ def make_dots(ctx): for g in glob.glob('doc-gen/Packet-*.md'): os.rename(g, g + '.old') - for (id, p) in d.items(): + for (id, p) in list(d.items()): md = 'doc-gen/Packet-0x%04x.md' % id dot = 'doc-gen/packets-around-0x%04x.gv' % id with OpenWrite(md) as f: @@ -7179,16 +7171,16 @@ def make_dots(ctx): covered_nodes = sorted(p.pre_set(d, 2) | p.post_set(d, 2)) covered_edges = [(a, b) for a in covered_nodes for b in covered_nodes if b in d[a].post] g = Graph() - g.default_vertex[u'shape'] = u'box' - # g[u'layout'] = u'twopi' - # g[u'root'] = u'0x%04x' % id + g.default_vertex['shape'] = 'box' + # g['layout'] = 'twopi' + # g['root'] = '0x%04x' % id for n in covered_nodes: - v = g.vertex(u'0x%04x' % n) - v[u'label'] = u'Packet \\N: %s' % d[n].name + v = g.vertex('0x%04x' % n) + v['label'] = 'Packet \\N: %s' % d[n].name if n == id: - v[u'style'] = u'filled' + v['style'] = 'filled' for (a, b) in covered_edges: - g.edge(u'0x%04x' % a, u'0x%04x' % b) + g.edge('0x%04x' % a, '0x%04x' % b) for n in covered_nodes: # the center node will be covered specially below if n == id: @@ -7206,10 +7198,10 @@ def make_dots(ctx): # don't show mere siblings unless also ancestor/descendent count += 1 if count: - v = g.vertex(u'0x%04x...pre' % n) - v[u'label'] = u'%d more' % count - v[u'style'] = u'dashed' - g.edge(v, u'0x%04x' % n) + v = g.vertex('0x%04x...pre' % n) + v['label'] = '%d more' % count + v['style'] = 'dashed' + g.edge(v, '0x%04x' % n) # strong forward links count = 0 for p in d[n].post: @@ -7218,36 +7210,36 @@ def make_dots(ctx): elif p not in covered_nodes: count += 1 if count: - v = g.vertex(u'0x%04x...post' % n) - v[u'label'] = u'%d more' % count - v[u'style'] = u'dashed' - g.edge(u'0x%04x' % n, v) + v = g.vertex('0x%04x...post' % n) + v['label'] = '%d more' % count + v['style'] = 'dashed' + g.edge('0x%04x' % n, v) # for the immediate node, also cover specials and weaks for p in d[id].pre: # (there are no weak backward specials) # strong backward specials if isinstance(p, SpecialEventOrigin): - g.edge(unicode(p.name), u'0x%04x' % id) + g.edge(str(p.name), '0x%04x' % id) # weak backward nodes elif id in d[p].xpost: - e = g.edge(u'0x%04x' % p, u'0x%04x' % id) - e[u'style']=u'dashed' - e[u'weight'] = u'0' + e = g.edge('0x%04x' % p, '0x%04x' % id) + e['style']='dashed' + e['weight'] = '0' for p in d[id].post: # strong forward specials if isinstance(p, SpecialEventOrigin): - g.edge(u'0x%04x' % id, unicode(p.name)) + g.edge('0x%04x' % id, str(p.name)) for p in d[id].xpost: # weak forward specials if isinstance(p, SpecialEventOrigin): - e = g.edge(u'0x%04x' % id, unicode(p.name)) - e[u'style'] = u'dashed' - e[u'weight'] = u'0' + e = g.edge('0x%04x' % id, str(p.name)) + e['style'] = 'dashed' + e['weight'] = '0' # weak forward nodes elif p not in covered_nodes: - e = g.edge(u'0x%04x' % id, u'0x%04x' % p) - e[u'style'] = u'dashed' - e[u'weight'] = u'0' + e = g.edge('0x%04x' % id, '0x%04x' % p) + e['style'] = 'dashed' + e['weight'] = '0' g.dot(f, False) diff --git a/version.make b/version.mk index 73ecc83..23bd071 100644 --- a/version.make +++ b/version.mk @@ -39,7 +39,7 @@ VENDOR_NAME := Vanilla VENDOR_POINT := 0 # URL where the source may be found (after searching for version number). # See AGPLv3 section 13 -VENDOR_SOURCE := https://github.com/themanaworld/tmwa +VENDOR_SOURCE := https://git.themanaworld.org/legacy/tmwa # Convenience VERSION_STRING := TMWA ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} dev${VERSION_DEVEL} +${VENDOR_POINT} (${VENDOR_NAME}) @@ -50,9 +50,38 @@ SO_SHORT := so.${ABI_VERSION} SO_LONG := ${SO_SHORT}.${VERSION_DOTS} # and thanks for all the fish +# This is a phony target, so that it always runs. +# Targets which depend on this will always have their recipes run. +FORCE:: ; +.PHONY: FORCE + +# Fully generate version.hpp here, where we have all the relevant information. +# version.mk is included by the top level Makefile, so simply explaning how to +# make it here will let it be built later, when needed. +# Note that some variable substitutions are slightly different here to use the +# name used by standard CMake macros, such as PROJECT_VERSION_TWEAK instead of +# VERSION_DEVEL. +src/conf/version.hpp: src/conf/version.hpp.in FORCE + sed -e 's/@VERSION_FULL@/${VERSION_FULL}/g' \ + -e 's/@VERSION_HASH@/${VERSION_HASH}/g' \ + -e 's/@VERSION_STRING@/${VERSION_STRING}/g' \ + -e 's/@PROJECT_VERSION_MAJOR@/${VERSION_MAJOR}/g' \ + -e 's/@PROJECT_VERSION_MINOR@/${VERSION_MINOR}/g' \ + -e 's/@PROJECT_VERSION_PATCH@/${VERSION_PATCH}/g' \ + -e 's/@PROJECT_VERSION_TWEAK@/${VERSION_DEVEL}/g' \ + -e 's/@VENDOR_NAME@/${VENDOR_NAME}/g' \ + -e 's/@VENDOR_POINT@/${VENDOR_POINT}/g' \ + -e 's|@VENDOR_SOURCE@|${VENDOR_SOURCE}|g' \ + -e 's/@ABI_VERSION@/${ABI_VERSION}/g' \ + -e 's/@SO_SHORT@/${SO_SHORT}/g' \ + -e 's/@SO_LONG@/${SO_LONG}/g' \ + $< > $@ + + version: @echo version '${VERSION_STRING}' @echo based on commit ${VERSION_FULL} aka ${VERSION_HASH} @echo source ${VENDOR_SOURCE} @echo abi version ${ABI_VERSION} @echo 'lib so -> ${SO_SHORT} -> ${SO_LONG}' +.PHONY: version |