From fb1e500e572774131d0891018332fc625b6a4c52 Mon Sep 17 00:00:00 2001
From: Ben Longbons <b.r.longbons@gmail.com>
Date: Mon, 5 Aug 2013 18:31:50 -0700
Subject: Use attoconf and proper versions

---
 .gitignore             |   2 +
 .gitmodules            |   3 ++
 .travis.yml            |   4 +-
 Makefile               | 102 ----------------------------------------------
 Makefile.in            | 107 +++++++++++++++++++++++++++++++++++++++++++++++++
 attoconf               |   1 +
 configure              |  72 +++++++++++++++++++++++++++++++++
 deps/attoconf          |   1 +
 make.defs              |  11 +----
 src/char/char.cpp      |   8 +---
 src/common/version.hpp |  77 ++++++++++++++++++++++++++---------
 src/ladmin/ladmin.cpp  |  39 ++++++++----------
 src/login/login.cpp    |  18 +++------
 src/map/clif.cpp       |   8 +---
 14 files changed, 273 insertions(+), 180 deletions(-)
 create mode 100644 .gitmodules
 delete mode 100644 Makefile
 create mode 100644 Makefile.in
 create mode 120000 attoconf
 create mode 100755 configure
 create mode 160000 deps/attoconf

diff --git a/.gitignore b/.gitignore
index e27b0e0..19569c2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,3 +14,5 @@
 /deps.make
 # tags file
 /tags
+# generated by configure
+/Makefile
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..a07e803
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "deps/attoconf"]
+	path = deps/attoconf
+	url = git://github.com/o11c/attoconf.git
diff --git a/.travis.yml b/.travis.yml
index f15f9d0..8717748 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,6 +15,7 @@ notifications:
     channels:   "chat.freenode.net#tmwa"
     on_success: always
     on_failure: always
+    use_notice: true
 
 ## Commands before installing prerequisites
 # before_install: git submodule update --init --recursive
@@ -37,7 +38,8 @@ install:
 
 ## Main test script
 script:
-  - make -k -j2 CXX=${REAL_CXX}\ -fabi-version=6 CPPFLAGS=-DQUIET
+  - ./configure CXX=${REAL_CXX}\ -fabi-version=6 CPPFLAGS=-DQUIET
+  - make -k -j2
 
 ## Do something after the main test script
 after_script:
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 44b3fc2..0000000
--- a/Makefile
+++ /dev/null
@@ -1,102 +0,0 @@
-#! /usr/bin/make -f
-SHELL=/bin/bash
-BUILD_DIR = obj
-default: login-server char-server map-server ladmin eathena-monitor
-.DELETE_ON_ERROR:
-include make.defs
-
-.PHONY: all clean common most
-# With no prerequisites, no target should ever be implicitly deleted.
-# With any prerequisites, those targets won't be (no patterns).
-.SECONDARY:
-# This does the same, but only for its prerequisites.
-# Unlike .SECONDARY, these may be patterns as well as normal prerequisites.
-# .PRECIOUS: %/.
-
-%/.:
-	+mkdir -p $@
-
-# The default recipe is suboptimal
-%.cpp: %.lpp
-	$(LEX) -o $@ $<
-%.cpp %.h: %.ypp
-	$(BISON) -d -o $*.cpp $<
-
-
-# All this duplication is required because make handles pattern rules specially
-${BUILD_DIR}/char/%.o: src/char/%.cpp | ${BUILD_DIR}/char/.
-	$(COMPILE.cpp) -o $@ $<
-${BUILD_DIR}/common/%.o: src/common/%.cpp | ${BUILD_DIR}/common/.
-	$(COMPILE.cpp) -o $@ $<
-${BUILD_DIR}/ladmin/%.o: src/ladmin/%.cpp | ${BUILD_DIR}/ladmin/.
-	$(COMPILE.cpp) -o $@ $<
-${BUILD_DIR}/login/%.o: src/login/%.cpp | ${BUILD_DIR}/login/.
-	$(COMPILE.cpp) -o $@ $<
-${BUILD_DIR}/map/%.o: src/map/%.cpp | ${BUILD_DIR}/map/.
-	$(COMPILE.cpp) -o $@ $<
-${BUILD_DIR}/tests/%.o: src/tests/%.cpp | ${BUILD_DIR}/tests/.
-	$(COMPILE.cpp) -o $@ $<
-${BUILD_DIR}/tool/%.o: src/tool/%.cpp | ${BUILD_DIR}/tool/.
-	$(COMPILE.cpp) -o $@ $<
-${BUILD_DIR}/gtest-all.o: ${GTEST_DIR}/src/gtest-all.cc | ${BUILD_DIR}/.
-	$(COMPILE.cpp) -I${GTEST_DIR} -DGTEST_HAS_PTHREAD=0 -o $@ $<
-
-
-MOSTPROGS = login-server char-server ladmin eathena-monitor
-PROGS = ${MOSTPROGS} map-server
-# Things to actually make
-all: ${PROGS}
-most: ${MOSTPROGS}
-clean:
-	rm -rf ${PROGS} ${BUILD_DIR}/
-common: ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/nullpo.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/extract.o
-magic: ${BUILD_DIR}/map/magic-interpreter-lexer.o ${BUILD_DIR}/map/magic-interpreter-parser.o ${BUILD_DIR}/map/magic-expr.o ${BUILD_DIR}/map/magic-interpreter-base.o ${BUILD_DIR}/map/magic-stmt.o ${BUILD_DIR}/map/magic.o
-
-# Top level programs
-login-server: ${BUILD_DIR}/login/login
-	cp -f $< $@
-char-server: ${BUILD_DIR}/char/char
-	cp -f $< $@
-map-server: ${BUILD_DIR}/map/map
-	cp -f $< $@
-ladmin: ${BUILD_DIR}/ladmin/ladmin
-	cp -f $< $@
-eathena-monitor: ${BUILD_DIR}/tool/eathena-monitor
-	cp -f $< $@
-
-${BUILD_DIR}/tests/main: ${BUILD_DIR}/tests/main.o $(patsubst src/%.cpp,obj/%.o,$(wildcard src/*/*_test.cpp)) ${BUILD_DIR}/gtest-all.o \
-	${BUILD_DIR}/common/extract.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/random.o
-test: ${BUILD_DIR}/tests/main
-	${TESTER} $< ${TEST_ARGS}
-
-# Executable dependencies - generated by hand
-${BUILD_DIR}/char/char: ${BUILD_DIR}/char/char.o ${BUILD_DIR}/char/inter.o ${BUILD_DIR}/char/int_party.o ${BUILD_DIR}/char/int_storage.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/extract.o
-${BUILD_DIR}/ladmin/ladmin: ${BUILD_DIR}/ladmin/ladmin.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/extract.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/utils.o
-${BUILD_DIR}/login/login: ${BUILD_DIR}/login/login.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/extract.o
-${BUILD_DIR}/map/map: ${BUILD_DIR}/map/map.o ${BUILD_DIR}/map/tmw.o ${BUILD_DIR}/map/magic-interpreter-lexer.o ${BUILD_DIR}/map/magic-interpreter-parser.o ${BUILD_DIR}/map/magic-interpreter-base.o ${BUILD_DIR}/map/magic-expr.o ${BUILD_DIR}/map/magic-stmt.o ${BUILD_DIR}/map/magic.o ${BUILD_DIR}/map/map.o ${BUILD_DIR}/map/chrif.o ${BUILD_DIR}/map/clif.o ${BUILD_DIR}/map/pc.o ${BUILD_DIR}/map/npc.o ${BUILD_DIR}/map/path.o ${BUILD_DIR}/map/itemdb.o ${BUILD_DIR}/map/mob.o ${BUILD_DIR}/map/script.o ${BUILD_DIR}/map/storage.o ${BUILD_DIR}/map/skill.o ${BUILD_DIR}/map/skill-pools.o ${BUILD_DIR}/map/atcommand.o ${BUILD_DIR}/map/battle.o ${BUILD_DIR}/map/intif.o ${BUILD_DIR}/map/trade.o ${BUILD_DIR}/map/party.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/map/grfio.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/nullpo.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/extract.o
-${BUILD_DIR}/tool/eathena-monitor: ${BUILD_DIR}/tool/eathena-monitor.o ${BUILD_DIR}/common/utils.o
-
-# silence build warnings for code beyond my control
-${BUILD_DIR}/map/magic-interpreter-lexer.o ${BUILD_DIR}/map/magic-interpreter-parser.o ${BUILD_DIR}/gtest-all.o: override WARNINGS=
-
-# deps.make is *NOT* automatically rebuilt normally
-# but the generated source files do need to be done first
-deps.make: src/map/magic-interpreter-parser.cpp src/map/magic-interpreter-lexer.cpp
-	for F in `find src/ -name '*.cpp'`; do \
-	    ${CXX} ${CPPFLAGS} -MM "$$F" -MT "$$(sed 's/src/$${BUILD_DIR}/;s/\.cpp/.o/' <<< "$$F")"; \
-	done > deps.make
-	echo '# vim: filetype=make' >> deps.make
-
-include deps.make
-
-prefix=/usr/local
-BACKUPS=numbered
-install:
-	install -d ${prefix}/bin/
-	install --backup=${BACKUPS} -t ${prefix}/bin/ $(wildcard ${PROGS})
-
-# might need changes later to handle static declarations (solution:
-# run ctags twice, specifying forward patterns for the declarations
-# and backward patterns for the definition)
-tags: $(shell git ls-files src/)
-	ctags --totals --c-kinds=+px -f $@ $^
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..d216b50
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,107 @@
+ifneq (${SRC_DIR},.)
+$(error out-of-tree builds not supported yet, sorry)
+endif
+# but there are bits working toward it
+
+vpath %.cpp ${SRC_DIR}
+vpath %.hpp ${SRC_DIR}
+
+SHELL=/bin/bash
+BUILD_DIR = obj
+default: login-server char-server map-server ladmin eathena-monitor
+.DELETE_ON_ERROR:
+include make.defs
+
+.PHONY: all clean common most
+# With no prerequisites, no target should ever be implicitly deleted.
+# With any prerequisites, those targets won't be (no patterns).
+.SECONDARY:
+# This does the same, but only for its prerequisites.
+# Unlike .SECONDARY, these may be patterns as well as normal prerequisites.
+# .PRECIOUS: %/.
+
+%/.:
+	+mkdir -p $@
+
+# The default recipe is suboptimal
+%.cpp: %.lpp
+	$(FLEX) -o $@ $<
+%.cpp %.h: %.ypp
+	$(BISON) -d -o $*.cpp $<
+
+
+# All this duplication is required because make handles pattern rules specially
+${BUILD_DIR}/char/%.o: src/char/%.cpp | ${BUILD_DIR}/char/.
+	$(COMPILE.cpp) -o $@ $<
+${BUILD_DIR}/common/%.o: src/common/%.cpp | ${BUILD_DIR}/common/.
+	$(COMPILE.cpp) -o $@ $<
+${BUILD_DIR}/ladmin/%.o: src/ladmin/%.cpp | ${BUILD_DIR}/ladmin/.
+	$(COMPILE.cpp) -o $@ $<
+${BUILD_DIR}/login/%.o: src/login/%.cpp | ${BUILD_DIR}/login/.
+	$(COMPILE.cpp) -o $@ $<
+${BUILD_DIR}/map/%.o: src/map/%.cpp | ${BUILD_DIR}/map/.
+	$(COMPILE.cpp) -o $@ $<
+${BUILD_DIR}/tests/%.o: src/tests/%.cpp | ${BUILD_DIR}/tests/.
+	$(COMPILE.cpp) -o $@ $<
+${BUILD_DIR}/tool/%.o: src/tool/%.cpp | ${BUILD_DIR}/tool/.
+	$(COMPILE.cpp) -o $@ $<
+${BUILD_DIR}/gtest-all.o: ${GTEST_DIR}/src/gtest-all.cc | ${BUILD_DIR}/.
+	$(COMPILE.cpp) -I${GTEST_DIR} -DGTEST_HAS_PTHREAD=0 -o $@ $<
+
+
+MOSTPROGS = login-server char-server ladmin eathena-monitor
+PROGS = ${MOSTPROGS} map-server
+# Things to actually make
+all: ${PROGS}
+most: ${MOSTPROGS}
+clean:
+	rm -rf ${PROGS} ${BUILD_DIR}/
+common: ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/nullpo.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/extract.o
+magic: ${BUILD_DIR}/map/magic-interpreter-lexer.o ${BUILD_DIR}/map/magic-interpreter-parser.o ${BUILD_DIR}/map/magic-expr.o ${BUILD_DIR}/map/magic-interpreter-base.o ${BUILD_DIR}/map/magic-stmt.o ${BUILD_DIR}/map/magic.o
+
+# Top level programs
+login-server: ${BUILD_DIR}/login/login
+	cp -f $< $@
+char-server: ${BUILD_DIR}/char/char
+	cp -f $< $@
+map-server: ${BUILD_DIR}/map/map
+	cp -f $< $@
+ladmin: ${BUILD_DIR}/ladmin/ladmin
+	cp -f $< $@
+eathena-monitor: ${BUILD_DIR}/tool/eathena-monitor
+	cp -f $< $@
+
+${BUILD_DIR}/tests/main: ${BUILD_DIR}/tests/main.o $(patsubst src/%.cpp,obj/%.o,$(wildcard src/*/*_test.cpp)) ${BUILD_DIR}/gtest-all.o \
+	${BUILD_DIR}/common/extract.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/random.o
+test: ${BUILD_DIR}/tests/main
+	${TESTER} $< ${TEST_ARGS}
+
+# Executable dependencies - generated by hand
+${BUILD_DIR}/char/char: ${BUILD_DIR}/char/char.o ${BUILD_DIR}/char/inter.o ${BUILD_DIR}/char/int_party.o ${BUILD_DIR}/char/int_storage.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/extract.o
+${BUILD_DIR}/ladmin/ladmin: ${BUILD_DIR}/ladmin/ladmin.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/extract.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/utils.o
+${BUILD_DIR}/login/login: ${BUILD_DIR}/login/login.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/extract.o
+${BUILD_DIR}/map/map: ${BUILD_DIR}/map/map.o ${BUILD_DIR}/map/tmw.o ${BUILD_DIR}/map/magic-interpreter-lexer.o ${BUILD_DIR}/map/magic-interpreter-parser.o ${BUILD_DIR}/map/magic-interpreter-base.o ${BUILD_DIR}/map/magic-expr.o ${BUILD_DIR}/map/magic-stmt.o ${BUILD_DIR}/map/magic.o ${BUILD_DIR}/map/map.o ${BUILD_DIR}/map/chrif.o ${BUILD_DIR}/map/clif.o ${BUILD_DIR}/map/pc.o ${BUILD_DIR}/map/npc.o ${BUILD_DIR}/map/path.o ${BUILD_DIR}/map/itemdb.o ${BUILD_DIR}/map/mob.o ${BUILD_DIR}/map/script.o ${BUILD_DIR}/map/storage.o ${BUILD_DIR}/map/skill.o ${BUILD_DIR}/map/skill-pools.o ${BUILD_DIR}/map/atcommand.o ${BUILD_DIR}/map/battle.o ${BUILD_DIR}/map/intif.o ${BUILD_DIR}/map/trade.o ${BUILD_DIR}/map/party.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/map/grfio.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/nullpo.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/extract.o
+${BUILD_DIR}/tool/eathena-monitor: ${BUILD_DIR}/tool/eathena-monitor.o ${BUILD_DIR}/common/utils.o
+
+# silence build warnings for code beyond my control
+${BUILD_DIR}/map/magic-interpreter-lexer.o ${BUILD_DIR}/map/magic-interpreter-parser.o ${BUILD_DIR}/gtest-all.o: override WARNINGS=
+
+# deps.make is *NOT* automatically rebuilt normally
+# but the generated source files do need to be done first
+deps.make: ${SRC_DIR}/src/map/magic-interpreter-parser.cpp ${SRC_DIR}/src/map/magic-interpreter-lexer.cpp
+	for F in `cd ${SRC_DIR}; find src/ -name '*.cpp'`; do \
+	    ${CXX} ${CPPFLAGS} -MM "$$F" -MT "$$(sed 's/src/$${BUILD_DIR}/;s/\.cpp/.o/' <<< "$$F")"; \
+	done > deps.make
+	echo '# vim: filetype=make' >> deps.make
+
+include deps.make
+
+install:
+	install -d ${BINDIR}
+	install --backup=${ENABLE_BACKUPS_DURING_INSTALL} -t ${BINDIR} $(wildcard ${PROGS})
+
+# might need changes later to handle static declarations (solution:
+# run ctags twice, specifying forward patterns for the declarations
+# and backward patterns for the definition)
+tags: $(shell git ls-files src/)
+	ctags --totals --c-kinds=+px -f $@ $^
diff --git a/attoconf b/attoconf
new file mode 120000
index 0000000..320176d
--- /dev/null
+++ b/attoconf
@@ -0,0 +1 @@
+deps/attoconf/attoconf/
\ No newline at end of file
diff --git a/configure b/configure
new file mode 100755
index 0000000..f28b002
--- /dev/null
+++ b/configure
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+
+#   Copyright 2013 Ben Longbons <b.r.longbons@gmail.com>
+#
+#   This file is part of The Mana World (Athena server)
+#
+#   attoconf is free software: you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   attoconf is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   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 subprocess
+import sys
+
+from attoconf.version import require_version
+require_version(0, 3)
+
+from attoconf.classy import add_slots
+from attoconf.lib.c import Cxx
+from attoconf.lib.lex import Flex
+from attoconf.lib.yacc import Bison
+from attoconf.lib.install import Install
+from attoconf.lib.make import Make
+from attoconf.types import enum
+
+
+def get_version(srcdir):
+    return subprocess.check_output(
+            ['git', 'describe', '--tags'],
+            cwd=srcdir).strip()
+
+
+@add_slots
+class Configuration(Cxx, Flex, Bison, Install, Make):
+    def general(self):
+        super(Configuration, self).general()
+        home = os.path.expanduser('~')
+        self.add_alias('--user', ['--prefix=%s' % home],
+                help='alias for --prefix=$HOME', hidden=False)
+
+    def features(self):
+        super(Configuration, self).features()
+        # TODO: check VERSION_CONTROL environment variable?
+        # not really important: this option is only to make Frost happy
+        self.add_option('--enable-backups-during-install', init='none',
+                type=enum('none', 'numbered', 'existing', 'simple'), check=None,
+                help='Back up existing files during \'make install\'', hidden=True,
+                help_var='CONTROL')
+
+
+def main():
+    srcdir = os.path.dirname(sys.argv[0])
+    proj = Configuration(srcdir)
+    proj.set_package('tmwa', get_version(srcdir), 'The Mana World (Athena server)')
+    proj.jiggle()
+    build = proj.build('.')
+    build.configure(sys.argv[1:], os.environ)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/deps/attoconf b/deps/attoconf
new file mode 160000
index 0000000..46e9b98
--- /dev/null
+++ b/deps/attoconf
@@ -0,0 +1 @@
+Subproject commit 46e9b987ff689c1acfe29c7b980298408d1b95a6
diff --git a/make.defs b/make.defs
index 0f35244..22579f1 100644
--- a/make.defs
+++ b/make.defs
@@ -1,14 +1,7 @@
 # vim: filetype=make
 #
-# defaults
-CXX = g++
-
-LEX = flex
-BISON = bison
-CXXFLAGS = ${DEBUG} ${OPT} ${WARNINGS}
-# these being separate use useful for development
-DEBUG = -g
-OPT = -pipe -O2
+# This file is deprecated. Everything here should be moved to 'configure'.
+CXXFLAGS += ${WARNINGS}
 WARNINGS = -include src/warnings.hpp
 
 # Location of gtest source tree. It must contain the file src/gtest-all.cc
diff --git a/src/char/char.cpp b/src/char/char.cpp
index 6108dca..fb1ca7d 100644
--- a/src/char/char.cpp
+++ b/src/char/char.cpp
@@ -2449,13 +2449,7 @@ void parse_char(int fd)
 
             case 0x7530:       // Athena情報所得
                 WFIFOW(fd, 0) = 0x7531;
-                WFIFOB(fd, 2) = ATHENA_MAJOR_VERSION;
-                WFIFOB(fd, 3) = ATHENA_MINOR_VERSION;
-                WFIFOB(fd, 4) = ATHENA_REVISION;
-                WFIFOB(fd, 5) = ATHENA_RELEASE_FLAG;
-                WFIFOB(fd, 6) = ATHENA_OFFICIAL_FLAG;
-                WFIFOB(fd, 7) = ATHENA_SERVER_INTER | ATHENA_SERVER_CHAR;
-                WFIFOW(fd, 8) = ATHENA_MOD_VERSION;
+                WFIFO_STRUCT(fd, 2, CURRENT_CHAR_SERVER_VERSION);
                 WFIFOSET(fd, 10);
                 RFIFOSKIP(fd, 2);
                 return;
diff --git a/src/common/version.hpp b/src/common/version.hpp
index d72f41e..4bdaa29 100644
--- a/src/common/version.hpp
+++ b/src/common/version.hpp
@@ -1,24 +1,61 @@
-/// Some constants to identify the version of (e)Athena
-/// The values are different if the client connects (-1,'T','M','W',flags32)
-// These numbers have never been changed while TMW
 #ifndef VERSION_HPP
 #define VERSION_HPP
-//When a server receives a 0x7530 packet from an admin connection,
-//it sends an 0x7531 packet with the following bytes
-# define ATHENA_MAJOR_VERSION    1   // Major Version
-# define ATHENA_MINOR_VERSION    0   // Minor Version
-# define ATHENA_REVISION         0   // Revision
-
-# define ATHENA_RELEASE_FLAG     1   // 1=Develop,0=Stable
-# define ATHENA_OFFICIAL_FLAG    1   // 1=Mod,0=Official
-
-// and a bitmask of these (the char server sends char and inter)
-# define ATHENA_SERVER_LOGIN     1   // login server
-# define ATHENA_SERVER_CHAR      2   // char server
-# define ATHENA_SERVER_INTER     4   // inter server
-# define ATHENA_SERVER_MAP       8   // map server
-
-// and this as two bytes
-# define ATHENA_MOD_VERSION   1052   // mod version (patch No.)
+
+// TODO generate this from ./configure
+
+# define TMWA_VERSION_MAJOR     13
+# define TMWA_VERSION_MINOR     8
+# define TMWA_VERSION_PATCH     5
+# define TMWA_DEVELOP_FLAG      1
+
+// TODO make these bitwise enums
+# define TMWA_FLAG_REGISTRATION 0x01
+
+# define TMWA_SERVER_LOGIN      0x01
+# define TMWA_SERVER_CHAR       0x02
+# define TMWA_SERVER_INTER      0x04
+# define TMWA_SERVER_MAP        0x08
+
+# define TMWA_VENDOR            "Vanilla"
+# define TMWA_VENDOR_VERSION    0
+
+struct Version
+{
+    uint8_t major;
+    uint8_t minor; // flavor1
+    uint8_t patch; // flavor2
+    uint8_t devel; // flavor3
+
+    uint8_t flags;
+    uint8_t which;
+    uint16_t vend;
+    // can't add vendor name yet
+};
+static_assert(sizeof(Version) == 8, "this is send over the network, can't change");
+
+constexpr Version CURRENT_LOGIN_SERVER_VERSION =
+{
+    TMWA_VERSION_MAJOR, TMWA_VERSION_MINOR, TMWA_VERSION_PATCH,
+    TMWA_DEVELOP_FLAG,
+
+    0, TMWA_SERVER_LOGIN,
+    TMWA_VENDOR_VERSION,
+};
+constexpr Version CURRENT_CHAR_SERVER_VERSION =
+{
+    TMWA_VERSION_MAJOR, TMWA_VERSION_MINOR, TMWA_VERSION_PATCH,
+    TMWA_DEVELOP_FLAG,
+
+    0, TMWA_SERVER_CHAR | TMWA_SERVER_INTER,
+    TMWA_VENDOR_VERSION,
+};
+constexpr Version CURRENT_MAP_SERVER_VERSION =
+{
+    TMWA_VERSION_MAJOR, TMWA_VERSION_MINOR, TMWA_VERSION_PATCH,
+    TMWA_DEVELOP_FLAG,
+
+    0, TMWA_SERVER_MAP,
+    TMWA_VENDOR_VERSION,
+};
 
 #endif // VERSION_HPP
diff --git a/src/ladmin/ladmin.cpp b/src/ladmin/ladmin.cpp
index 2581456..9f4691c 100644
--- a/src/ladmin/ladmin.cpp
+++ b/src/ladmin/ladmin.cpp
@@ -1942,28 +1942,18 @@ void parse_fromlogin(int fd)
             case 0x7531:       // Displaying of the version of the login-server
                 if (RFIFOREST(fd) < 10)
                     return;
+            {
                 Iprintf("  Login-Server [%s:%d]\n", loginserverip,
                          loginserverport);
-                if (RFIFOB(login_fd, 5) == 0)
-                {
-                    Iprintf("  eAthena version stable-%d.%d",
-                            RFIFOB(login_fd, 2),
-                            RFIFOB(login_fd, 3));
-                }
-                else
-                {
-                    Iprintf("  eAthena version dev-%d.%d",
-                            RFIFOB(login_fd, 2),
-                            RFIFOB(login_fd, 3));
-                }
-                if (RFIFOB(login_fd, 4) == 0)
-                    Iprintf(" revision %d", RFIFOB(login_fd, 4));
-                if (RFIFOB(login_fd, 6) == 0)
-                {
-                    Iprintf("%d.\n", RFIFOW(login_fd, 8));
-                }
-                else
-                    Iprintf("-mod%d.\n", RFIFOW(login_fd, 8));
+                Version version;
+                RFIFO_STRUCT(login_fd, 2, version);
+                Iprintf("  tmwA version %hhu.%hhu.%hhu (dev? %hhu) (flags %hhx) (which %hhx) (vend %hu)\n",
+                        version.major, version.minor, version.patch,
+                        version.devel,
+
+                        version.flags, version.which,
+                        version.vend);
+            }
                 bytes_to_read = 0;
                 RFIFOSKIP(fd, 10);
                 break;
@@ -2872,8 +2862,13 @@ int do_init(int argc, ZString *argv)
     set_defaultparse(parse_fromlogin);
 
     Iprintf("EAthena login-server administration tool.\n");
-    Iprintf("(for eAthena version %d.%d.%d.)\n", ATHENA_MAJOR_VERSION,
-             ATHENA_MINOR_VERSION, ATHENA_REVISION);
+    Version version = CURRENT_LOGIN_SERVER_VERSION;
+    Iprintf("for tmwA version %hhu.%hhu.%hhu (dev? %hhu) (flags %hhx) (which %hhx) (vend %hu)\n",
+            version.major, version.minor, version.patch,
+            version.devel,
+
+            version.flags, version.which,
+            version.vend);
 
     LADMIN_LOG("Ladmin is ready.\n");
     Iprintf("Ladmin is \033[1;32mready\033[0m.\n\n");
diff --git a/src/login/login.cpp b/src/login/login.cpp
index 852cd3d..031abd7 100644
--- a/src/login/login.cpp
+++ b/src/login/login.cpp
@@ -1654,13 +1654,7 @@ void parse_admin(int fd)
                 LOGIN_LOG("'ladmin': Sending of the server version (ip: %s)\n",
                            ip);
                 WFIFOW(fd, 0) = 0x7531;
-                WFIFOB(fd, 2) = ATHENA_MAJOR_VERSION;
-                WFIFOB(fd, 3) = ATHENA_MINOR_VERSION;
-                WFIFOB(fd, 4) = ATHENA_REVISION;
-                WFIFOB(fd, 5) = ATHENA_RELEASE_FLAG;
-                WFIFOB(fd, 6) = ATHENA_OFFICIAL_FLAG;
-                WFIFOB(fd, 7) = ATHENA_SERVER_LOGIN;
-                WFIFOW(fd, 8) = ATHENA_MOD_VERSION;
+                WFIFO_STRUCT(fd, 2, CURRENT_LOGIN_SERVER_VERSION);
                 WFIFOSET(fd, 10);
                 RFIFOSKIP(fd, 2);
                 break;
@@ -3110,12 +3104,12 @@ void parse_login(int fd)
                 LOGIN_LOG("Sending of the server version (ip: %s)\n",
                            ip);
                 WFIFOW(fd, 0) = 0x7531;
-                WFIFOB(fd, 2) = -1;
-                WFIFOB(fd, 3) = 'T';
-                WFIFOB(fd, 4) = 'M';
-                WFIFOB(fd, 5) = 'W';
-                WFIFOL(fd, 6) = new_account_flag ? 1 : 0;
+            {
+                Version version = CURRENT_LOGIN_SERVER_VERSION;
+                version.flags = new_account_flag ? 1 : 0;
+                WFIFO_STRUCT(fd, 2, version);
                 WFIFOSET(fd, 10);
+            }
                 RFIFOSKIP(fd, 2);
                 break;
 
diff --git a/src/map/clif.cpp b/src/map/clif.cpp
index 494e09f..fa208be 100644
--- a/src/map/clif.cpp
+++ b/src/map/clif.cpp
@@ -5451,13 +5451,7 @@ void clif_parse(int fd)
         {
             case 0x7530:       // Athena情報所得
                 WFIFOW(fd, 0) = 0x7531;
-                WFIFOB(fd, 2) = ATHENA_MAJOR_VERSION;
-                WFIFOB(fd, 3) = ATHENA_MINOR_VERSION;
-                WFIFOB(fd, 4) = ATHENA_REVISION;
-                WFIFOB(fd, 5) = ATHENA_RELEASE_FLAG;
-                WFIFOB(fd, 6) = ATHENA_OFFICIAL_FLAG;
-                WFIFOB(fd, 7) = ATHENA_SERVER_MAP;
-                WFIFOW(fd, 8) = ATHENA_MOD_VERSION;
+                WFIFO_STRUCT(fd, 2, CURRENT_MAP_SERVER_VERSION);
                 WFIFOSET(fd, 10);
                 RFIFOSKIP(fd, 2);
                 break;
-- 
cgit v1.2.3-70-g09d2