summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2014-03-15 19:34:59 -0700
committerBen Longbons <b.r.longbons@gmail.com>2014-03-16 18:58:48 -0700
commitc812c92d1a1835f0bda783e709481188c8d92225 (patch)
treeb401ede48a088ad1aaed88fe3b997cd26ff7ae08 /src/common
parentde9ee1b9754af9d954487121947352f32d7ebb7e (diff)
downloadtmwa-c812c92d1a1835f0bda783e709481188c8d92225.tar.gz
tmwa-c812c92d1a1835f0bda783e709481188c8d92225.tar.bz2
tmwa-c812c92d1a1835f0bda783e709481188c8d92225.tar.xz
tmwa-c812c92d1a1835f0bda783e709481188c8d92225.zip
Clean up header organization
Diffstat (limited to 'src/common')
-rw-r--r--src/common/GNUmakefile7
-rw-r--r--src/common/config_parse.cpp154
-rw-r--r--src/common/config_parse.hpp36
-rw-r--r--src/common/const_array.hpp132
-rw-r--r--src/common/core.cpp124
-rw-r--r--src/common/core.hpp22
-rw-r--r--src/common/db.cpp3
-rw-r--r--src/common/db.hpp180
-rw-r--r--src/common/dumb_ptr.hpp276
-rw-r--r--src/common/extract.cpp62
-rw-r--r--src/common/extract.hpp223
-rw-r--r--src/common/extract_test.cpp334
-rw-r--r--src/common/human_time_diff.hpp86
-rw-r--r--src/common/human_time_diff_test.cpp83
-rw-r--r--src/common/intern-pool.hpp41
-rw-r--r--src/common/intern-pool_test.cpp20
-rw-r--r--src/common/ip.cpp114
-rw-r--r--src/common/ip.hpp164
-rw-r--r--src/common/ip.py14
-rw-r--r--src/common/ip_test.cpp332
-rw-r--r--src/common/iter.hpp97
-rw-r--r--src/common/iter_test.cpp82
-rw-r--r--src/common/matrix.hpp50
-rw-r--r--src/common/md5calc.cpp352
-rw-r--r--src/common/md5calc.hpp64
-rw-r--r--src/common/md5calc_test.cpp30
-rw-r--r--src/common/mmo.hpp380
-rw-r--r--src/common/nullpo.cpp28
-rw-r--r--src/common/nullpo.hpp41
-rw-r--r--src/common/operators.hpp47
-rw-r--r--src/common/random.cpp8
-rw-r--r--src/common/random.hpp69
-rw-r--r--src/common/random.t.hpp23
-rw-r--r--src/common/random2.hpp74
-rw-r--r--src/common/socket.cpp474
-rw-r--r--src/common/socket.hpp371
-rw-r--r--src/common/timer.cpp201
-rw-r--r--src/common/timer.hpp30
-rw-r--r--src/common/timer.t.hpp68
-rw-r--r--src/common/utils.cpp101
-rw-r--r--src/common/utils.hpp140
-rw-r--r--src/common/utils2.hpp256
-rw-r--r--src/common/version.cpp53
-rw-r--r--src/common/version.hpp69
44 files changed, 0 insertions, 5515 deletions
diff --git a/src/common/GNUmakefile b/src/common/GNUmakefile
deleted file mode 100644
index 917ce0e..0000000
--- a/src/common/GNUmakefile
+++ /dev/null
@@ -1,7 +0,0 @@
-.SUFFIXES:
-common:
- ${MAKE} -C ../.. common
-clean:
- rm -r ../../obj/common/
-%::
- ${MAKE} -C ../.. obj/common/$@
diff --git a/src/common/config_parse.cpp b/src/common/config_parse.cpp
deleted file mode 100644
index d677d8e..0000000
--- a/src/common/config_parse.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-#include "config_parse.hpp"
-// config_parse.hpp - Framework for per-server config parsers.
-//
-// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com>
-//
-// This file is part of The Mana World (Athena server)
-//
-// This program 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.
-//
-// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
-
-#include "../strings/xstring.hpp"
-#include "../strings/zstring.hpp"
-
-#include "../io/cxxstdio.hpp"
-#include "../io/line.hpp"
-
-#include "version.hpp"
-
-#include "../poison.hpp"
-
-bool is_comment(XString line)
-{
- return not line or line.startswith("//");
-}
-
-template<class ZS>
-inline
-bool config_split_impl(ZS line, XString *key, ZS *value)
-{
- // unconditionally fail if line contains control characters
- if (std::find_if(line.begin(), line.end(),
- [](unsigned char c) { return c < ' '; }
- ) != line.end())
- return false;
- // try to find a colon, fail if not found
- typename ZS::iterator colon = std::find(line.begin(), line.end(), ':');
- if (colon == line.end())
- return false;
-
- *key = line.xislice_h(colon).strip();
- // move past the colon and any spaces
- ++colon;
- *value = line.xislice_t(colon).lstrip();
- return true;
-}
-
-// eventually this should go away
-bool config_split(ZString line, XString *key, ZString *value)
-{
- return config_split_impl(line, key, value);
-}
-// and use this instead
-bool config_split(XString line, XString *key, XString *value)
-{
- return config_split_impl(line, key, value);
-}
-
-/// Master config parser. This handles 'import' and 'version-ge' etc.
-/// Then it defers to the inferior parser for a line it does not understand.
-bool load_config_file(ZString filename, ConfigItemParser slave)
-{
- io::LineReader in(filename);
- if (!in.is_open())
- {
- PRINTF("Unable to open file: %s\n", filename);
- return false;
- }
- io::Line line;
- bool rv = true;
- while (in.read_line(line))
- {
- if (is_comment(line.text))
- continue;
- XString key;
- ZString value;
- if (!config_split(line.text, &key, &value))
- {
- line.error("Bad config line");
- rv = false;
- continue;
- }
- if (key == "import")
- {
- rv &= load_config_file(value, slave);
- continue;
- }
- else if (key == "version-lt")
- {
- Version vers;
- if (!extract(value, &vers))
- {
- rv = false;
- continue;
- }
- if (CURRENT_VERSION < vers)
- continue;
- break;
- }
- else if (key == "version-le")
- {
- Version vers;
- if (!extract(value, &vers))
- {
- rv = false;
- continue;
- }
- if (CURRENT_VERSION <= vers)
- continue;
- break;
- }
- else if (key == "version-gt")
- {
- Version vers;
- if (!extract(value, &vers))
- {
- rv = false;
- continue;
- }
- if (CURRENT_VERSION > vers)
- continue;
- break;
- }
- else if (key == "version-ge")
- {
- Version vers;
- if (!extract(value, &vers))
- {
- rv = false;
- continue;
- }
- if (CURRENT_VERSION >= vers)
- continue;
- break;
- }
- else if (!slave(key, value))
- {
- line.error("Bad config key or value");
- rv = false;
- continue;
- }
- // nothing to see here, move along
- }
- return rv;
-}
diff --git a/src/common/config_parse.hpp b/src/common/config_parse.hpp
deleted file mode 100644
index 6a55174..0000000
--- a/src/common/config_parse.hpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef TMWA_COMMON_CONFIG_PARSE_HPP
-#define TMWA_COMMON_CONFIG_PARSE_HPP
-// config_parse.hpp - Framework for per-server config parsers.
-//
-// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com>
-//
-// This file is part of The Mana World (Athena server)
-//
-// This program 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.
-//
-// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
-
-# include "../sanity.hpp"
-
-# include "../strings/fwd.hpp"
-
-typedef bool (*ConfigItemParser)(XString key, ZString value);
-
-bool is_comment(XString line);
-bool config_split(ZString line, XString *key, ZString *value);
-bool config_split(XString line, XString *key, XString *value);
-
-/// Master config parser. This handles 'import' and 'version-ge' etc.
-/// Then it defers to the inferior parser for a line it does not understand.
-bool load_config_file(ZString filename, ConfigItemParser slave);
-
-#endif // TMWA_COMMON_CONFIG_PARSE_HPP
diff --git a/src/common/const_array.hpp b/src/common/const_array.hpp
deleted file mode 100644
index fe15728..0000000
--- a/src/common/const_array.hpp
+++ /dev/null
@@ -1,132 +0,0 @@
-#ifndef CONST_ARRAY_HPP
-#define CONST_ARRAY_HPP
-// const_array.hpp - just a pointer-to-const and a length
-//
-// Copyright © 2011-2012 Ben Longbons <b.r.longbons@gmail.com>
-//
-// This file is part of The Mana World (Athena server)
-//
-// This program 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.
-//
-// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
-
-# include "../sanity.hpp"
-
-# include <cstring>
-
-# include <iterator>
-# include <ostream>
-# include <vector>
-
-# ifdef WORKAROUND_GCC46_COMPILER
-// constexpr is buggy with templates in this version
-// Is this still needed now that const_string is removed?
-# define constexpr /* nothing */
-# endif
-
-// TODO see if I ever actually use this, and not the subclass
-template<class T>
-class const_array
-{
- const T *d;
- size_t n;
-public:
- typedef const T *iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
-
- constexpr
- const_array(std::nullptr_t)
- : d(nullptr), n(0)
- {}
-
- constexpr
- const_array(const T *p, size_t z)
- : d(p), n(z)
- {}
-
- constexpr
- const_array(const T *b, const T *e)
- : d(b), n(e - b)
- {}
-
- const_array(std::initializer_list<T> list)
- : d(list.begin()), n(list.size())
- {}
-
- // Implicit conversion from std::vector
- const_array(const std::vector<T>& v)
- : d(v.data()), n(v.size())
- {}
-
- // but disallow conversion from a temporary
- const_array(std::vector<T>&&) = delete;
-
- // Oops. see src/warnings.hpp
- constexpr
- const T *data() const { return d; }
- constexpr
- size_t size() const { return n; }
- constexpr
- bool empty() const { return not n; }
- constexpr explicit
- operator bool() const { return n; }
-
- constexpr
- std::pair<const_array, const_array> cut(size_t o) const
- {
- return {const_array(d, o), const_array(d + o, n - o)};
- }
-
- constexpr
- const_array first(size_t o) const
- {
- return cut(o).first;
- }
-
- constexpr
- const_array last(size_t l) const
- {
- return cut(size() - l).second;
- }
-
- constexpr
- const_array after(size_t o) const
- {
- return cut(o).second;
- }
-
- constexpr
- iterator begin() const { return d; }
- constexpr
- iterator end() const { return d + n; }
- constexpr
- reverse_iterator rbegin() const { return reverse_iterator(end()); }
- constexpr
- reverse_iterator rend() const { return reverse_iterator(begin()); }
-
- constexpr
- const T& front() const { return *begin(); }
- constexpr
- const T& back() const { return *rbegin(); }
-
- // This probably shouldn't be used, but I'm adding it for porting.
- T& operator[](size_t i)
- {
- return const_cast<T&>(d[i]);
- }
-};
-
-# ifdef WORKAROUND_GCC46_COMPILER
-# undef constexpr
-# endif
-
-#endif // CONST_ARRAY_HPP
diff --git a/src/common/core.cpp b/src/common/core.cpp
deleted file mode 100644
index d57e970..0000000
--- a/src/common/core.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-#include "core.hpp"
-
-#include <sys/wait.h>
-
-#include <unistd.h>
-
-#include <csignal>
-#include <cstdlib>
-#include <ctime>
-
-#include "../strings/zstring.hpp"
-
-#include "../io/cxxstdio.hpp"
-
-#include "random.hpp"
-#include "socket.hpp"
-#include "timer.hpp"
-
-#include "../poison.hpp"
-
-// Added by Gabuzomeu
-//
-// This is an implementation of signal() using sigaction() for portability.
-// (sigaction() is POSIX; signal() is not.) Taken from Stevens' _Advanced
-// Programming in the UNIX Environment_.
-//
-typedef void(*sigfunc)(int);
-static
-sigfunc compat_signal(int signo, sigfunc func)
-{
- struct sigaction sact, oact;
-
- sact.sa_handler = func;
- sigfillset(&sact.sa_mask);
- sigdelset(&sact.sa_mask, SIGSEGV);
- sigdelset(&sact.sa_mask, SIGBUS);
- sigdelset(&sact.sa_mask, SIGTRAP);
- sigdelset(&sact.sa_mask, SIGILL);
- sigdelset(&sact.sa_mask, SIGFPE);
- sact.sa_flags = 0;
-
- if (sigaction(signo, &sact, &oact) < 0)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wold-style-cast"
- return SIG_ERR;
-#pragma GCC diagnostic pop
-
- return oact.sa_handler;
-}
-
-volatile
-bool runflag = true;
-
-static
-void chld_proc(int)
-{
- wait(NULL);
-}
-static
-void sig_proc(int)
-{
- for (int i = 1; i < 31; ++i)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wold-style-cast"
- compat_signal(i, SIG_IGN);
-#pragma GCC diagnostic pop
- runflag = false;
-}
-
-/*
- Note about fatal signals:
-
- Under certain circumstances,
- the following signals MUST not be ignored:
- SIGFPE, SIGSEGV, SIGILL
- Unless you use SA_SIGINFO and *carefully* check the origin,
- that means they must be SIG_DFL.
- */
-int main(int argc, char **argv)
-{
- // ZString args[argc]; is (deliberately!) not supported by clang yet
- ZString *args = static_cast<ZString *>(alloca(argc * sizeof(ZString)));
- for (int i = 0; i < argc; ++i)
- args[i] = ZString(strings::really_construct_from_a_pointer, argv[i], nullptr);
- do_init(argc, args);
-
- if (!runflag)
- {
- PRINTF("Fatal error during startup; exiting\n");
- return 1;
- }
- // set up exit handlers *after* the initialization has happened.
- // This is because term_func is likely to depend on successful init.
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wold-style-cast"
- compat_signal(SIGPIPE, SIG_IGN);
-#pragma GCC diagnostic pop
- compat_signal(SIGTERM, sig_proc);
- compat_signal(SIGINT, sig_proc);
- compat_signal(SIGCHLD, chld_proc);
-
- // Signal to create coredumps by system when necessary (crash)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wold-style-cast"
- compat_signal(SIGSEGV, SIG_DFL);
- compat_signal(SIGBUS, SIG_DFL);
- compat_signal(SIGTRAP, SIG_DFL);
- compat_signal(SIGILL, SIG_DFL);
- compat_signal(SIGFPE, SIG_DFL);
-#pragma GCC diagnostic pop
-
- atexit(term_func);
-
- while (runflag)
- {
- // TODO - if timers take a long time to run, this
- // may wait too long in sendrecv
- tick_t now = milli_clock::now();
- interval_t next = do_timer(now);
- do_sendrecv(next);
- do_parsepacket();
- }
-}
diff --git a/src/common/core.hpp b/src/common/core.hpp
deleted file mode 100644
index 8141e9c..0000000
--- a/src/common/core.hpp
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef CORE_HPP
-#define CORE_HPP
-
-# include "../sanity.hpp"
-
-# include "../strings/fwd.hpp"
-
-/// core.c contains a server-independent main() function
-/// and then runs a do_sendrecv loop
-
-/// When this is cleared, the server exits gracefully.
-extern volatile bool runflag;
-
-/// This is an external function defined by each server
-/// This function must register stuff for the parse loop
-extern int do_init(int, ZString *);
-
-/// Cleanup function called whenever a signal kills us
-/// or when if we manage to exit() gracefully.
-extern void term_func(void);
-
-#endif // CORE_HPP
diff --git a/src/common/db.cpp b/src/common/db.cpp
deleted file mode 100644
index cc58ad8..0000000
--- a/src/common/db.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "db.hpp"
-
-#include "../poison.hpp"
diff --git a/src/common/db.hpp b/src/common/db.hpp
deleted file mode 100644
index 0384f1c..0000000
--- a/src/common/db.hpp
+++ /dev/null
@@ -1,180 +0,0 @@
-#ifndef DB_HPP
-#define DB_HPP
-// db.hpp - convenience wrappers over std::map<K, V>
-//
-// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com>
-//
-// This file is part of The Mana World (Athena server)
-//
-// This program 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.
-//
-// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
-
-# include "../sanity.hpp"
-
-# include <map>
-# include <memory>
-
-template<class K, class V>
-class Map
-{
- typedef std::map<K, V> Impl;
-
- Impl impl;
-public:
- Map() = default;
- Map(std::initializer_list<std::pair<const K, V>> il)
- : impl(il)
- {}
- typedef typename Impl::iterator iterator;
- typedef typename Impl::const_iterator const_iterator;
-
- iterator begin() { return impl.begin(); }
- iterator end() { return impl.end(); }
- const_iterator begin() const { return impl.begin(); }
- const_iterator end() const { return impl.end(); }
-
- V *search(const K& k)
- {
- iterator it = impl.find(k);
- if (it == impl.end())
- return nullptr;
- return &it->second;
- }
- const V *search(const K& k) const
- {
- const_iterator it = impl.find(k);
- if (it == impl.end())
- return nullptr;
- return &it->second;
- }
- void insert(const K& k, V v)
- {
- // As far as I can tell, this is the simplest way to
- // implement move-only insert-with-replacement.
- iterator it = impl.lower_bound(k);
- // invariant: if it is valid, it->first >= k
- if (it != impl.end() && it->first == k)
- it->second = std::move(v);
- else
- it = impl.insert(std::pair<K, V>(std::move(k), std::move(v))).first;
- return (void)&it->second;
-
- }
- V *init(const K& k)
- {
- return &impl[k];
- }
- void erase(const K& k)
- {
- impl.erase(k);
- }
- void clear()
- {
- impl.clear();
- }
- bool empty() const
- {
- return impl.empty();
- }
- size_t size() const
- {
- return impl.size();
- }
-};
-
-template<class K, class V>
-class DMap
-{
- typedef Map<K, V> Impl;
-
- Impl impl;
-public:
- typedef typename Impl::iterator iterator;
- typedef typename Impl::const_iterator const_iterator;
-
- iterator begin() { return impl.begin(); }
- iterator end() { return impl.end(); }
- const_iterator begin() const { return impl.begin(); }
- const_iterator end() const { return impl.end(); }
-
- // const V& ? with a static default V?
- V get(const K& k)
- {
- V *vp = impl.search(k);
- return vp ? *vp : V();
- }
- void put(const K& k, V v)
- {
- if (v == V())
- impl.erase(k);
- else
- impl.insert(k, std::move(v));
- }
- void clear()
- {
- impl.clear();
- }
- bool empty() const
- {
- return impl.empty();
- }
- size_t size() const
- {
- return impl.size();
- }
-};
-
-template<class K, class V>
-class UPMap
-{
- typedef std::unique_ptr<V> U;
- typedef Map<K, U> Impl;
-
- Impl impl;
-public:
- typedef typename Impl::iterator iterator;
- typedef typename Impl::const_iterator const_iterator;
-
- iterator begin() { return impl.begin(); }
- iterator end() { return impl.end(); }
- const_iterator begin() const { return impl.begin(); }
- const_iterator end() const { return impl.end(); }
-
- // const V& ? with a static default V?
- V *get(const K& k)
- {
- U *up = impl.search(k);
- return up ? up->get() : nullptr;
- }
- void put(const K& k, U v)
- {
- if (!v)
- impl.erase(k);
- else
- impl.insert(k, std::move(v));
- }
- void clear()
- {
- impl.clear();
- }
- bool empty() const
- {
- return impl.empty();
- }
- size_t size() const
- {
- return impl.size();
- }
-};
-
-#endif // DB_HPP
diff --git a/src/common/dumb_ptr.hpp b/src/common/dumb_ptr.hpp
deleted file mode 100644
index bf97f22..0000000
--- a/src/common/dumb_ptr.hpp
+++ /dev/null
@@ -1,276 +0,0 @@
-#ifndef TMWA_COMMON_DUMB_PTR_HPP
-#define TMWA_COMMON_DUMB_PTR_HPP
-// ptr.hpp - temporary new/delete wrappers
-//
-// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com>
-//
-// This file is part of The Mana World (Athena server)
-//
-// This program 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.
-//
-// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
-
-# include "../sanity.hpp"
-
-# include <cstring>
-
-# include <algorithm>
-
-# include "../strings/astring.hpp"
-# include "../strings/zstring.hpp"
-# include "../strings/xstring.hpp"
-
-# include "const_array.hpp"
-
-// unmanaged new/delete-able pointer
-// should be replaced by std::unique_ptr<T>
-template<class T>
-class dumb_ptr
-{
- template<class U>
- friend class dumb_ptr;
- T *impl;
-public:
- explicit
- dumb_ptr(T *p=nullptr)
- : impl(p)
- {}
- template<class U>
- dumb_ptr(dumb_ptr<U> p)
- : impl(p.impl)
- {}
- dumb_ptr(std::nullptr_t)
- : impl(nullptr)
- {}
-
- void delete_()
- {
- delete impl;
- *this = nullptr;
- }
- template<class... A>
- void new_(A&&... a)
- {
- impl = new T(std::forward<A>(a)...);
- }
- template<class... A>
- static
- dumb_ptr<T> make(A&&... a)
- {
- return dumb_ptr<T>(new T(std::forward<A>(a)...));
- }
- dumb_ptr& operator = (std::nullptr_t)
- {
- impl = nullptr;
- return *this;
- }
-
- T& operator *() const
- {
- return *impl;
- }
- T *operator->() const
- {
- return impl;
- }
-
- explicit
- operator bool() const
- {
- return impl;
- }
- bool operator !() const
- {
- return !impl;
- }
-
- friend bool operator == (dumb_ptr l, dumb_ptr r)
- {
- return l.impl == r.impl;
- }
- friend bool operator != (dumb_ptr l, dumb_ptr r)
- {
- return !(l == r);
- }
-};
-
-// unmanaged new/delete-able pointer
-// should be replaced by std::unique_ptr<T[]> or std::vector<T>
-template<class T>
-class dumb_ptr<T[]>
-{
- T *impl;
- size_t sz;
-public:
- dumb_ptr() : impl(), sz() {}
- dumb_ptr(std::nullptr_t)
- : impl(nullptr), sz(0) {}
- dumb_ptr(T *p, size_t z)
- : impl(p)
- , sz(z)
- {}
-
- void delete_()
- {
- delete[] impl;
- *this = nullptr;
- }
- void new_(size_t z)
- {
- impl = new T[z]();
- sz = z;
- }
- static
- dumb_ptr<T[]> make(size_t z)
- {
- return dumb_ptr<T[]>(new T[z](), z);
- }
- dumb_ptr& operator = (std::nullptr_t)
- {
- impl = nullptr;
- sz = 0;
- return *this;
- }
-
- size_t size() const
- {
- return sz;
- }
- void resize(size_t z)
- {
- if (z == sz)
- return;
- T *np = new T[z]();
- // not exception-safe, but we don't have a dtor anyway
- size_t i = std::min(z, sz);
- while (i-->0)
- np[i] = std::move(impl[i]);
- delete[] impl;
- impl = np;
- sz = z;
- }
-
- T& operator[](size_t i) const
- {
- return impl[i];
- }
-
- explicit
- operator bool() const
- {
- return impl;
- }
- bool operator !() const
- {
- return !impl;
- }
-
- friend bool operator == (dumb_ptr l, dumb_ptr r)
- {
- return l.impl == r.impl;
- }
- friend bool operator != (dumb_ptr l, dumb_ptr r)
- {
- return !(l == r);
- }
-};
-
-struct dumb_string
-{
- dumb_ptr<char[]> impl;
-
- dumb_string()
- : impl()
- {}
- dumb_string(char *) = delete;
- // copy ctor, copy assign, and dtor are all default
-
- static dumb_string copy(const char *b, const char *e)
- {
- dumb_string rv;
- rv.impl.new_((e - b) + 1);
- std::copy(b, e, &rv.impl[0]);
- return rv;
- }
- static dumb_string copy(const char *sz)
- {
- return dumb_string::copy(sz, sz + strlen(sz));
- }
- static dumb_string copys(XString s)
- {
- return dumb_string::copy(&*s.begin(), &*s.end());
- }
- static
-# ifndef __clang__
- __attribute__((warning("shouldn't use this - slice instead")))
-# endif
- dumb_string copyn(const char *sn, size_t n)
- {
- return dumb_string::copy(sn, sn + strnlen(sn, n));
- }
-
- static
- dumb_string fake(ZString p)
- {
- dumb_string rv;
- size_t len = p.size();
- rv.impl = dumb_ptr<char[]>(const_cast<char *>(p.c_str()), len);
- return rv;
- }
-
- dumb_string dup() const
- {
- return dumb_string::copy(&impl[0]);
- }
- void delete_()
- {
- impl.delete_();
- }
-
- const char *c_str() const
- {
- return &impl[0];
- }
-
- operator ZString() const
- {
- return ZString(strings::really_construct_from_a_pointer, c_str(), nullptr);
- }
-
- AString str() const
- {
- return ZString(*this);
- }
-
- char& operator[](size_t i) const
- {
- return impl[i];
- }
-
- explicit
- operator bool() const
- {
- return bool(impl);
- }
- bool operator !() const
- {
- return !impl;
- }
-};
-
-inline
-const char *convert_for_printf(dumb_string ds)
-{
- return ds.c_str();
-}
-
-#endif // TMWA_COMMON_DUMB_PTR_HPP
diff --git a/src/common/extract.cpp b/src/common/extract.cpp
deleted file mode 100644
index 378986d..0000000
--- a/src/common/extract.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "extract.hpp"
-// extract.cpp - a simple, hierarchical, tokenizer
-//
-// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com>
-//
-// This file is part of The Mana World (Athena server)
-//
-// This program 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.
-//
-// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
-
-#include "../strings/astring.hpp"
-#include "../strings/xstring.hpp"
-#include "../strings/vstring.hpp"
-
-#include "../poison.hpp"
-
-bool extract(XString str, XString *rv)
-{
- *rv = str;
- return true;
-}
-
-bool extract(XString str, AString *rv)
-{
- *rv = str;
- return true;
-}
-
-bool extract(XString str, struct global_reg *var)
-{
- return extract(str,
- record<','>(&var->str, &var->value));
-}
-
-bool extract(XString str, struct item *it)
-{
- XString ignored;
- return extract(str,
- record<',', 11>(
- &it->id,
- &it->nameid,
- &it->amount,
- &it->equip,
- &ignored,
- &ignored,
- &ignored,
- &ignored,
- &ignored,
- &ignored,
- &ignored,
- &ignored));
-}
diff --git a/src/common/extract.hpp b/src/common/extract.hpp
deleted file mode 100644
index 31cf111..0000000
--- a/src/common/extract.hpp
+++ /dev/null
@@ -1,223 +0,0 @@
-#ifndef EXTRACT_HPP
-#define EXTRACT_HPP
-// extract.hpp - a simple, hierarchical, tokenizer
-//
-// Copyright © 2012-2013 Ben Longbons <b.r.longbons@gmail.com>
-//
-// This file is part of The Mana World (Athena server)
-//
-// This program 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.
-//
-// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
-
-# include "../sanity.hpp"
-
-# include <algorithm>
-
-# include "../strings/xstring.hpp"
-
-# include "const_array.hpp"
-# include "mmo.hpp"
-# include "utils.hpp"
-
-template<class T, typename=typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, char>::value && !std::is_same<T, bool>::value>::type>
-bool extract(XString str, T *iv)
-{
- if (!str || str.size() > 20)
- return false;
- if (!((str.front() == '-' && std::is_signed<T>::value)
- || ('0' <= str.front() && str.front() <= '9')))
- return false;
- // needs a NUL, but can't always be given one. TODO VString?
- char buf[20 + 1];
- std::copy(str.begin(), str.end(), buf);
- buf[str.size()] = '\0';
-
- char *end;
- errno = 0;
- if (std::is_signed<T>::value)
- {
- long long v = strtoll(buf, &end, 10);
- if (errno || *end)
- return false;
- *iv = v;
- return *iv == v;
- }
- else
- {
- unsigned long long v = strtoull(buf, &end, 10);
- if (errno || *end)
- return false;
- *iv = v;
- return *iv == v;
- }
-}
-
-inline
-bool extract(XString str, TimeT *tv)
-{
- return extract(str, &tv->value);
-}
-
-// extra typename=void to workaround some duplicate overload rule
-template<class T, typename=typename std::enable_if<std::is_enum<T>::value>::type, typename=void>
-bool extract(XString str, T *iv)
-{
- typedef typename underlying_type<T>::type U;
- U v;
- // defer to integer version
- if (!extract(str, &v))
- return false;
- // TODO check bounds using enum min/max as in SSCANF
- *iv = static_cast<T>(v);
- return true;
-}
-
-bool extract(XString str, XString *rv);
-
-bool extract(XString str, AString *rv);
-
-template<uint8_t N>
-bool extract(XString str, VString<N> *out)
-{
- if (str.size() > N)
- return false;
- *out = str;
- return true;
-}
-
-template<class T>
-class LStripper
-{
-public:
- T impl;
-};
-
-template<class T>
-LStripper<T> lstripping(T v)
-{
- return {v};
-}
-
-template<class T>
-bool extract(XString str, LStripper<T> out)
-{
- return extract(str.lstrip(), out.impl);
-}
-
-// basically just a std::tuple
-// but it provides its data members publically
-template<char split, int n, class... T>
-class Record;
-template<char split, int n>
-class Record<split, n>
-{
-};
-template<char split, int n, class F, class... R>
-class Record<split, n, F, R...>
-{
-public:
- F frist;
- Record<split, n - 1, R...> rest;
-public:
- Record(F f, R... r)
- : frist(f), rest(r...)
- {}
-};
-template<char split, class... T>
-Record<split, sizeof...(T), T...> record(T... t)
-{
- return Record<split, sizeof...(T), T...>(t...);
-}
-template<char split, int n, class... T>
-Record<split, n, T...> record(T... t)
-{
- static_assert(0 < n && n < sizeof...(T), "don't be silly");
- return Record<split, n, T...>(t...);
-}
-
-template<char split, int n>
-bool extract(XString str, Record<split, n>)
-{
- return !str;
-}
-
-template<char split, int n, class F, class... R>
-bool extract(XString str, Record<split, n, F, R...> rec)
-{
- XString::iterator s = std::find(str.begin(), str.end(), split);
- XString::iterator s2 = s;
- if (s2 != str.end())
- ++s2;
- XString head = str.xislice_h(s);
- XString tail = str.xislice_t(s2);
- if (s == str.end())
- return (extract(head, rec.frist) && n <= 1)
- || (!head && n <= 0);
-
- return (extract(head, rec.frist) || n <= 0)
- && extract(tail, rec.rest);
-}
-
-template<char split, class T>
-struct VRecord
-{
- std::vector<T> *arr;
-};
-
-template<char split, class T>
-VRecord<split, T> vrec(std::vector<T> *arr)
-{
- return {arr};
-}
-
-template<char split, class T>
-bool extract(XString str, VRecord<split, T> rec)
-{
- if (!str)
- return true;
- XString::iterator s = std::find(str.begin(), str.end(), split);
- rec.arr->emplace_back();
- if (s == str.end())
- return extract(str, &rec.arr->back());
- return extract(str.xislice_h(s), &rec.arr->back())
- && extract(str.xislice_t(s + 1), rec);
-}
-
-bool extract(XString str, struct global_reg *var);
-
-bool extract(XString str, struct item *it);
-
-inline
-bool extract(XString str, MapName *m)
-{
- XString::iterator it = std::find(str.begin(), str.end(), '.');
- str = str.xislice_h(it);
- VString<15> tmp;
- bool rv = extract(str, &tmp);
- *m = tmp;
- return rv;
-}
-
-inline
-bool extract(XString str, CharName *out)
-{
- VString<23> tmp;
- if (extract(str, &tmp))
- {
- *out = CharName(tmp);
- return true;
- }
- return false;
-}
-
-#endif // EXTRACT_HPP
diff --git a/src/common/extract_test.cpp b/src/common/extract_test.cpp
deleted file mode 100644
index 3d0610e..0000000
--- a/src/common/extract_test.cpp
+++ /dev/null
@@ -1,334 +0,0 @@
-#include "extract.hpp"
-
-#include <gtest/gtest.h>
-
-#include "../strings/xstring.hpp"
-
-TEST(extract, record_int)
-{
- int x, y, z;
- x = y = z = 0;
- EXPECT_FALSE(extract("1 2 3 4 ", record<' '>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(3, z);
- x = y = z = 0;
- EXPECT_FALSE(extract("1 2 3 4", record<' '>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(3, z);
- x = y = z = 0;
- EXPECT_TRUE(extract("1 2 3 ", record<' '>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(3, z);
- x = y = z = 0;
- EXPECT_TRUE(extract("1 2 3", record<' '>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(3, z);
- x = y = z = 0;
- EXPECT_FALSE(extract("1 2 ", record<' '>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
- EXPECT_FALSE(extract("1 2", record<' '>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
- EXPECT_FALSE(extract("1 ", record<' '>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(0, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
- EXPECT_FALSE(extract("1", record<' '>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(0, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
- EXPECT_FALSE(extract(" ", record<' '>(&x, &y, &z)));
- EXPECT_EQ(0, x);
- EXPECT_EQ(0, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
- EXPECT_FALSE(extract("", record<' '>(&x, &y, &z)));
- EXPECT_EQ(0, x);
- EXPECT_EQ(0, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
-
- EXPECT_FALSE(extract("1 2 3 4 ", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(3, z);
- x = y = z = 0;
- EXPECT_FALSE(extract("1 2 3 4", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(3, z);
- x = y = z = 0;
- EXPECT_TRUE(extract("1 2 3 ", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(3, z);
- x = y = z = 0;
- EXPECT_TRUE(extract("1 2 3", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(3, z);
- x = y = z = 0;
- EXPECT_TRUE(extract("1 2 ", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
- EXPECT_TRUE(extract("1 2", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
- EXPECT_FALSE(extract("1 ", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(0, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
- EXPECT_FALSE(extract("1", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(0, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
- EXPECT_FALSE(extract(" ", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ(0, x);
- EXPECT_EQ(0, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
- EXPECT_FALSE(extract("", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ(0, x);
- EXPECT_EQ(0, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
-
- EXPECT_FALSE(extract("1 2 3 4 ", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(3, z);
- x = y = z = 0;
- EXPECT_FALSE(extract("1 2 3 4", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(3, z);
- x = y = z = 0;
- EXPECT_TRUE(extract("1 2 3 ", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(3, z);
- x = y = z = 0;
- EXPECT_TRUE(extract("1 2 3", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(3, z);
- x = y = z = 0;
- EXPECT_TRUE(extract("1 2 ", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
- EXPECT_TRUE(extract("1 2", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(2, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
- EXPECT_TRUE(extract("1 ", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(0, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
- EXPECT_TRUE(extract("1", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ(1, x);
- EXPECT_EQ(0, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
- EXPECT_FALSE(extract(" ", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ(0, x);
- EXPECT_EQ(0, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
- EXPECT_FALSE(extract("", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ(0, x);
- EXPECT_EQ(0, y);
- EXPECT_EQ(0, z);
- x = y = z = 0;
-}
-
-TEST(extract, record_str)
-{
- XString x, y, z;
- x = y = z = "";
- EXPECT_FALSE(extract("1 2 3 4 ", record<' '>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("3", z);
- x = y = z = "";
- EXPECT_FALSE(extract("1 2 3 4", record<' '>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("3", z);
- x = y = z = "";
- EXPECT_TRUE(extract("1 2 3 ", record<' '>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("3", z);
- x = y = z = "";
- EXPECT_TRUE(extract("1 2 3", record<' '>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("3", z);
- x = y = z = "";
- EXPECT_TRUE(extract("1 2 ", record<' '>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("", z);
- x = y = z = "";
- EXPECT_FALSE(extract("1 2", record<' '>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("", z);
- x = y = z = "";
- EXPECT_FALSE(extract("1 ", record<' '>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("", y);
- EXPECT_EQ("", z);
- x = y = z = "";
- EXPECT_FALSE(extract("1", record<' '>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("", y);
- EXPECT_EQ("", z);
- x = y = z = "";
- EXPECT_FALSE(extract(" ", record<' '>(&x, &y, &z)));
- EXPECT_EQ("", x);
- EXPECT_EQ("", y);
- EXPECT_EQ("", z);
- x = y = z = "";
- EXPECT_FALSE(extract("", record<' '>(&x, &y, &z)));
- EXPECT_EQ("", x);
- EXPECT_EQ("", y);
- EXPECT_EQ("", z);
- x = y = z = "";
-
- EXPECT_FALSE(extract("1 2 3 4 ", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("3", z);
- x = y = z = "";
- EXPECT_FALSE(extract("1 2 3 4", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("3", z);
- x = y = z = "";
- EXPECT_TRUE(extract("1 2 3 ", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("3", z);
- x = y = z = "";
- EXPECT_TRUE(extract("1 2 3", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("3", z);
- x = y = z = "";
- EXPECT_TRUE(extract("1 2 ", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("", z);
- x = y = z = "";
- EXPECT_TRUE(extract("1 2", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("", z);
- x = y = z = "";
- EXPECT_TRUE(extract("1 ", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("", y);
- EXPECT_EQ("", z);
- x = y = z = "";
- EXPECT_FALSE(extract("1", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("", y);
- EXPECT_EQ("", z);
- x = y = z = "";
- EXPECT_TRUE(extract(" ", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ("", x);
- EXPECT_EQ("", y);
- EXPECT_EQ("", z);
- x = y = z = "";
- EXPECT_FALSE(extract("", record<' ', 2>(&x, &y, &z)));
- EXPECT_EQ("", x);
- EXPECT_EQ("", y);
- EXPECT_EQ("", z);
- x = y = z = "";
-
- EXPECT_FALSE(extract("1 2 3 4 ", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("3", z);
- x = y = z = "";
- EXPECT_FALSE(extract("1 2 3 4", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("3", z);
- x = y = z = "";
- EXPECT_TRUE(extract("1 2 3 ", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("3", z);
- x = y = z = "";
- EXPECT_TRUE(extract("1 2 3", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("3", z);
- x = y = z = "";
- EXPECT_TRUE(extract("1 2 ", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("", z);
- x = y = z = "";
- EXPECT_TRUE(extract("1 2", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("2", y);
- EXPECT_EQ("", z);
- x = y = z = "";
- EXPECT_TRUE(extract("1 ", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("", y);
- EXPECT_EQ("", z);
- x = y = z = "";
- EXPECT_TRUE(extract("1", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ("1", x);
- EXPECT_EQ("", y);
- EXPECT_EQ("", z);
- x = y = z = "";
- EXPECT_TRUE(extract(" ", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ("", x);
- EXPECT_EQ("", y);
- EXPECT_EQ("", z);
- x = y = z = "";
- EXPECT_TRUE(extract("", record<' ', 1>(&x, &y, &z)));
- EXPECT_EQ("", x);
- EXPECT_EQ("", y);
- EXPECT_EQ("", z);
- x = y = z = "";
-}
-
-TEST(extract, mapname)
-{
- MapName map;
- EXPECT_TRUE(extract("abc", &map));
- EXPECT_EQ(map, "abc");
- EXPECT_TRUE(extract("abc.gat", &map));
- EXPECT_EQ(map, "abc");
- EXPECT_TRUE(extract("abcdefghijklmno", &map));
- EXPECT_EQ(map, "abcdefghijklmno");
- EXPECT_TRUE(extract("abcdefghijklmno.gat", &map));
- EXPECT_EQ(map, "abcdefghijklmno");
-}
diff --git a/src/common/human_time_diff.hpp b/src/common/human_time_diff.hpp
deleted file mode 100644
index b8040b8..0000000
--- a/src/common/human_time_diff.hpp
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef TMWA_COMMON_HUMAN_TIME_DIFF_HPP
-#define TMWA_COMMON_HUMAN_TIME_DIFF_HPP
-// human_time_diff.hpp - broken deltas
-//
-// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com>
-//
-// This file is part of The Mana World (Athena server)
-//
-// This program 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.
-//
-// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
-
-# include "../sanity.hpp"
-
-# include "../strings/xstring.hpp"
-
-# include "extract.hpp"
-
-struct HumanTimeDiff
-{
- short year, month, day, hour, minute, second;
-
- explicit
- operator bool()
- {
- return year || month || day || hour || minute || second;
- }
-
- bool operator !()
- {
- return !bool(*this);
- }
-};
-
-inline
-bool extract(XString str, HumanTimeDiff *iv)
-{
- // str is a sequence of [-+]?[0-9]+([ay]|m|[jd]|h|mn|s)
- // there are NO spaces here
- // parse by counting the number starts
- auto is_num = [](char c)
- { return c == '-' || c == '+' || ('0' <= c && c <= '9'); };
- if (!str || !is_num(str.front()))
- return false;
- *iv = HumanTimeDiff{};
- while (str)
- {
- auto it = std::find_if_not(str.begin(), str.end(), is_num);
- auto it2 = std::find_if(it, str.end(), is_num);
- XString number = str.xislice_h(it);
- XString suffix = str.xislice(it, it2);
- str = str.xislice_t(it2);
-
- short *ptr = nullptr;
- if (suffix == "y" || suffix == "a")
- ptr = &iv->year;
- else if (suffix == "m")
- ptr = &iv->month;
- else if (suffix == "j" || suffix == "d")
- ptr = &iv->day;
- else if (suffix == "h")
- ptr = &iv->hour;
- else if (suffix == "mn")
- ptr = &iv->minute;
- else if (suffix == "s")
- ptr = &iv->second;
- else
- return false;
- if (number.startswith('+') && !number.startswith("+-"))
- number = number.xslice_t(1);
- if (*ptr || !extract(number, ptr))
- return false;
- }
- return true;
-}
-
-#endif // TMWA_COMMON_HUMAN_TIME_DIFF_HPP
diff --git a/src/common/human_time_diff_test.cpp b/src/common/human_time_diff_test.cpp
deleted file mode 100644
index d3ddad1..0000000
--- a/src/common/human_time_diff_test.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-#include "human_time_diff.hpp"
-
-#include <gtest/gtest.h>
-
-// a sequence of [-+]?[0-9]+([ay]|m|[jd]|h|mn|s)
-
-TEST(humantimediff, single)
-{
- HumanTimeDiff diff;
-
- EXPECT_TRUE(extract("42y", &diff));
- EXPECT_EQ(42, diff.year);
- EXPECT_EQ(0, diff.month);
- EXPECT_EQ(0, diff.day);
- EXPECT_EQ(0, diff.hour);
- EXPECT_EQ(0, diff.minute);
- EXPECT_EQ(0, diff.second);
-
- EXPECT_TRUE(extract("42m", &diff));
- EXPECT_EQ(0, diff.year);
- EXPECT_EQ(42, diff.month);
- EXPECT_EQ(0, diff.day);
- EXPECT_EQ(0, diff.hour);
- EXPECT_EQ(0, diff.minute);
- EXPECT_EQ(0, diff.second);
-
- EXPECT_TRUE(extract("42d", &diff));
- EXPECT_EQ(0, diff.year);
- EXPECT_EQ(0, diff.month);
- EXPECT_EQ(42, diff.day);
- EXPECT_EQ(0, diff.hour);
- EXPECT_EQ(0, diff.minute);
- EXPECT_EQ(0, diff.second);
-
- EXPECT_TRUE(extract("42h", &diff));
- EXPECT_EQ(0, diff.year);
- EXPECT_EQ(0, diff.month);
- EXPECT_EQ(0, diff.day);
- EXPECT_EQ(42, diff.hour);
- EXPECT_EQ(0, diff.minute);
- EXPECT_EQ(0, diff.second);
-
- EXPECT_TRUE(extract("42mn", &diff));
- EXPECT_EQ(0, diff.year);
- EXPECT_EQ(0, diff.month);
- EXPECT_EQ(0, diff.day);
- EXPECT_EQ(0, diff.hour);
- EXPECT_EQ(42, diff.minute);
- EXPECT_EQ(0, diff.second);
-
- EXPECT_TRUE(extract("42s", &diff));
- EXPECT_EQ(0, diff.year);
- EXPECT_EQ(0, diff.month);
- EXPECT_EQ(0, diff.day);
- EXPECT_EQ(0, diff.hour);
- EXPECT_EQ(0, diff.minute);
- EXPECT_EQ(42, diff.second);
-
- EXPECT_TRUE(extract("+42y", &diff));
- EXPECT_EQ(42, diff.year);
- EXPECT_TRUE(extract("-42y", &diff));
- EXPECT_EQ(-42, diff.year);
- EXPECT_FALSE(extract("++42y", &diff));
- EXPECT_FALSE(extract("+-42y", &diff));
- EXPECT_FALSE(extract("-+42y", &diff));
- EXPECT_FALSE(extract("--42y", &diff));
- EXPECT_FALSE(extract("4+2y", &diff));
- EXPECT_FALSE(extract("42z", &diff));
-}
-
-TEST(humantimediff, multiple)
-{
- HumanTimeDiff diff;
-
- EXPECT_TRUE(extract("42y23m-2d", &diff));
- EXPECT_EQ(42, diff.year);
- EXPECT_EQ(23, diff.month);
- EXPECT_EQ(-2, diff.day);
- EXPECT_EQ(0, diff.hour);
- EXPECT_EQ(0, diff.minute);
- EXPECT_EQ(0, diff.second);
- EXPECT_FALSE(extract("1y2y", &diff));
-}
diff --git a/src/common/intern-pool.hpp b/src/common/intern-pool.hpp
deleted file mode 100644
index e75a359..0000000
--- a/src/common/intern-pool.hpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef INTERN_POOL_HPP
-#define INTERN_POOL_HPP
-
-# include <cassert>
-
-# include <map>
-# include <vector>
-
-# include "../strings/rstring.hpp"
-# include "../strings/zstring.hpp"
-# include "../strings/xstring.hpp"
-
-class InternPool
-{
- std::map<RString, size_t> known;
- std::vector<RString> names;
-public:
- size_t intern(XString name_)
- {
- // TODO just look up the XString, the memory should not move by now
- RString name = name_;
- // hm, I could change this to do aliases
- auto pair = known.insert({name, known.size()});
- if (pair.second)
- names.push_back(name);
- assert (known.size() == names.size());
- return pair.first->second;
- }
-
- ZString outtern(size_t sz) const
- {
- return names[sz];
- }
-
- size_t size() const
- {
- return known.size();
- }
-};
-
-#endif //INTERN_POOL_HPP
diff --git a/src/common/intern-pool_test.cpp b/src/common/intern-pool_test.cpp
deleted file mode 100644
index bf17b67..0000000
--- a/src/common/intern-pool_test.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "intern-pool.hpp"
-
-#include <gtest/gtest.h>
-
-#include "../strings/base.hpp"
-
-TEST(InternPool, whydoesthisalwaysneedasecondname)
-{
- InternPool p;
- EXPECT_EQ(0, p.size());
- EXPECT_EQ(0, p.intern("hello"));
- EXPECT_EQ(0, p.intern("hello"));
- EXPECT_EQ(1, p.size());
- EXPECT_EQ(1, p.intern("world"));
- EXPECT_EQ(0, p.intern("hello"));
- EXPECT_EQ(1, p.intern("world"));
- EXPECT_EQ(2, p.size());
- EXPECT_EQ("hello", p.outtern(0));
- EXPECT_EQ("world", p.outtern(1));
-}
diff --git a/src/common/ip.cpp b/src/common/ip.cpp
deleted file mode 100644
index 146734a..0000000
--- a/src/common/ip.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-#include "ip.hpp"
-// ip.cpp - Implementation of IP address functions.
-//
-// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com>
-//
-// This file is part of The Mana World (Athena server)
-//
-// This program 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.
-//
-// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
-
-#include "../strings/xstring.hpp"
-#include "../strings/vstring.hpp"
-
-#include "../io/cxxstdio.hpp"
-
-#include "../poison.hpp"
-
-bool extract(XString str, IP4Address *rv)
-{
- if (str.endswith('.'))
- return false;
- uint8_t buf[4];
- if (extract(str, record<'.'>(&buf[0], &buf[1], &buf[2], &buf[3])))
- {
- *rv = IP4Address(buf);
- return true;
- }
- return false;
-}
-
-bool extract(XString str, IP4Mask *rv)
-{
- IP4Address a, m;
- unsigned b;
- XString l, r;
- if (str.endswith('/'))
- return false;
- if (extract(str, record<'/'>(&l, &r)))
- {
- // a.b.c.d/e.f.g.h or a.b.c.d/n
- if (!extract(l, &a))
- return false;
- if (extract(r, &m))
- {
- *rv = IP4Mask(a, m);
- return true;
- }
- if (!extract(r, &b) || b > 32)
- return false;
- }
- else
- {
- // a.b.c.d or a.b.c.d. or a.b.c. or a.b. or a.
- if (extract(str, &a))
- {
- *rv = IP4Mask(a, IP4_BROADCAST);
- return true;
- }
- if (!str.endswith('.'))
- return false;
- uint8_t d[4] {};
- if (extract(str, record<'.'>(&d[0], &d[1], &d[2], &d[3])))
- b = 32;
- else if (extract(str, record<'.'>(&d[0], &d[1], &d[2])))
- b = 24;
- else if (extract(str, record<'.'>(&d[0], &d[1])))
- b = 16;
- else if (extract(str, record<'.'>(&d[0])))
- b = 8;
- else
- return false;
- a = IP4Address(d);
- }
- // a is set; need to construct m from b
- if (b == 0)
- m = IP4Address();
- else if (b == 32)
- m = IP4_BROADCAST;
- else
- {
- uint32_t s = -1;
- s <<= (32 - b);
- m = IP4Address({
- static_cast<uint8_t>(s >> 24),
- static_cast<uint8_t>(s >> 16),
- static_cast<uint8_t>(s >> 8),
- static_cast<uint8_t>(s >> 0),
- });
- }
- *rv = IP4Mask(a, m);
- return true;
-}
-
-VString<15> convert_for_printf(IP4Address a_)
-{
- const uint8_t *a = a_.bytes();
- return STRNPRINTF(16, "%hhu.%hhu.%hhu.%hhu", a[0], a[1], a[2], a[3]);
-}
-
-VString<31> convert_for_printf(IP4Mask a)
-{
- return STRNPRINTF(32, "%s/%s",
- a.addr(), a.mask());
-}
diff --git a/src/common/ip.hpp b/src/common/ip.hpp
deleted file mode 100644
index d6e6f04..0000000
--- a/src/common/ip.hpp
+++ /dev/null
@@ -1,164 +0,0 @@
-#ifndef TMWA_COMMON_IP_HPP
-#define TMWA_COMMON_IP_HPP
-// ip.hpp - classes to deal with IP addresses.
-//
-// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com>
-//
-// This file is part of The Mana World (Athena server)
-//
-// This program 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.
-//
-// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
-
-# include "../sanity.hpp"
-
-# include <netinet/in.h>
-
-# include "../strings/fwd.hpp"
-
-# include "extract.hpp"
-
-// TODO - in the long run ports belong here also
-// and of course, IPv6 stuff.
-// But what about unix socket addresses?
-
-/// Helper function
-template<class T, size_t n>
-constexpr
-bool _ce_a_lt(T (&a)[n], T (&b)[n], size_t i=0)
-{
- return (i != n
- && (a[i] < b[i]
- || (a[i] == b[i]
- && _ce_a_lt(a, b, i + 1))));
-}
-
-/// A 32-bit Ipv4 address. Does not include a port.
-/// Guaranteed to be laid out like the network wants.
-class IP4Address
-{
- uint8_t _addr[4];
-public:
- constexpr
- IP4Address()
- : _addr{}
- {}
- constexpr explicit
- IP4Address(const uint8_t (&a)[4])
- : _addr{a[0], a[1], a[2], a[3]}
- {}
- explicit
- IP4Address(struct in_addr addr)
- {
- static_assert(sizeof(addr) == sizeof(_addr), "4 bytes");
- *this = IP4Address(reinterpret_cast<const uint8_t (&)[4]>(addr));
- }
- explicit
- operator struct in_addr() const
- {
- return reinterpret_cast<const struct in_addr&>(_addr);
- }
-
- constexpr friend
- IP4Address operator & (IP4Address l, IP4Address r)
- {
- return IP4Address({
- static_cast<uint8_t>(l._addr[0] & r._addr[0]),
- static_cast<uint8_t>(l._addr[1] & r._addr[1]),
- static_cast<uint8_t>(l._addr[2] & r._addr[2]),
- static_cast<uint8_t>(l._addr[3] & r._addr[3]),
- });
- }
-
- IP4Address& operator &= (IP4Address m)
- { return *this = *this & m; }
-
- const uint8_t *bytes() const
- { return _addr; }
-
- constexpr friend
- bool operator < (IP4Address l, IP4Address r)
- {
- return _ce_a_lt(l._addr, r._addr);
- }
-
- constexpr friend
- bool operator > (IP4Address l, IP4Address r)
- {
- return _ce_a_lt(r._addr, l._addr);
- }
-
- constexpr friend
- bool operator >= (IP4Address l, IP4Address r)
- {
- return !_ce_a_lt(l._addr, r._addr);
- }
-
- constexpr friend
- bool operator <= (IP4Address l, IP4Address r)
- {
- return !_ce_a_lt(r._addr, l._addr);
- }
-
- constexpr friend
- bool operator == (IP4Address l, IP4Address r)
- {
- return !(l < r || r < l);
- }
-
- constexpr friend
- bool operator != (IP4Address l, IP4Address r)
- {
- return (l < r || r < l);
- }
-};
-
-class IP4Mask
-{
- IP4Address _addr, _mask;
-public:
- constexpr
- IP4Mask() : _addr(), _mask()
- {}
- constexpr
- IP4Mask(IP4Address a, IP4Address m) : _addr(a & m), _mask(m)
- {}
-
- constexpr
- IP4Address addr() const
- { return _addr; }
- constexpr
- IP4Address mask() const
- { return _mask; }
-
- constexpr
- bool covers(IP4Address a) const
- {
- return (a & _mask) == _addr;
- }
-};
-
-
-constexpr
-IP4Address IP4_LOCALHOST({127, 0, 0, 1});
-constexpr
-IP4Address IP4_BROADCAST({255, 255, 255, 255});
-
-
-VString<15> convert_for_printf(IP4Address a);
-VString<31> convert_for_printf(IP4Mask m);
-
-bool extract(XString str, IP4Address *iv);
-
-bool extract(XString str, IP4Mask *iv);
-
-#endif // TMWA_COMMON_IP_HPP
diff --git a/src/common/ip.py b/src/common/ip.py
deleted file mode 100644
index e6a8183..0000000
--- a/src/common/ip.py
+++ /dev/null
@@ -1,14 +0,0 @@
-class IP4Address(object):
- ''' print an IP4Address
- '''
- __slots__ = ('_value')
- name = 'IP4Address'
- enabled = True
-
- def __init__(self, value):
- self._value = value
-
- def to_string(self):
- addr = self._value['_addr']
- addr = tuple(int(addr[i]) for i in range(4))
- return '%d.%d.%d.%d' % addr
diff --git a/src/common/ip_test.cpp b/src/common/ip_test.cpp
deleted file mode 100644
index 7ef1047..0000000
--- a/src/common/ip_test.cpp
+++ /dev/null
@@ -1,332 +0,0 @@
-#include "ip.hpp"
-
-#include <gtest/gtest.h>
-
-#include "../io/cxxstdio.hpp"
-
-#define CB(X) (std::integral_constant<bool, (X)>::value)
-TEST(ip4addr, cmp)
-{
- constexpr static
- IP4Address a = IP4_LOCALHOST;
- constexpr static
- IP4Address b = IP4_BROADCAST;
-
- EXPECT_FALSE(CB(a < a));
- EXPECT_TRUE (CB(a < b));
- EXPECT_FALSE(CB(b < a));
- EXPECT_FALSE(CB(b < b));
-
- EXPECT_FALSE(CB(a > a));
- EXPECT_FALSE(CB(a > b));
- EXPECT_TRUE (CB(b > a));
- EXPECT_FALSE(CB(b > b));
-
- EXPECT_TRUE (CB(a <= a));
- EXPECT_TRUE (CB(a <= b));
- EXPECT_FALSE(CB(b <= a));
- EXPECT_TRUE (CB(b <= b));
-
- EXPECT_TRUE (CB(a >= a));
- EXPECT_FALSE(CB(a >= b));
- EXPECT_TRUE (CB(b >= a));
- EXPECT_TRUE (CB(b >= b));
-
- EXPECT_TRUE (CB(a == a));
- EXPECT_FALSE(CB(a == b));
- EXPECT_FALSE(CB(b == a));
- EXPECT_TRUE (CB(b == b));
-
- EXPECT_FALSE(CB(a != a));
- EXPECT_TRUE (CB(a != b));
- EXPECT_TRUE (CB(b != a));
- EXPECT_FALSE(CB(b != b));
-}
-
-TEST(ip4addr, str)
-{
- IP4Address a;
- EXPECT_EQ("0.0.0.0", STRNPRINTF(17, "%s", a));
- EXPECT_EQ("127.0.0.1", STRNPRINTF(17, "%s", IP4_LOCALHOST));
- EXPECT_EQ("255.255.255.255", STRNPRINTF(17, "%s", IP4_BROADCAST));
-}
-
-TEST(ip4addr, extract)
-{
- IP4Address a;
- EXPECT_TRUE(extract("0.0.0.0", &a));
- EXPECT_EQ("0.0.0.0", STRNPRINTF(16, "%s", a));
- EXPECT_TRUE(extract("127.0.0.1", &a));
- EXPECT_EQ("127.0.0.1", STRNPRINTF(16, "%s", a));
- EXPECT_TRUE(extract("255.255.255.255", &a));
- EXPECT_EQ("255.255.255.255", STRNPRINTF(16, "%s", a));
- EXPECT_TRUE(extract("1.2.3.4", &a));
- EXPECT_EQ("1.2.3.4", STRNPRINTF(16, "%s", a));
-
- EXPECT_FALSE(extract("1.2.3.4.5", &a));
- EXPECT_FALSE(extract("1.2.3.4.", &a));
- EXPECT_FALSE(extract("1.2.3.", &a));
- EXPECT_FALSE(extract("1.2.3", &a));
- EXPECT_FALSE(extract("1.2.", &a));
- EXPECT_FALSE(extract("1.2", &a));
- EXPECT_FALSE(extract("1.", &a));
- EXPECT_FALSE(extract("1", &a));
- EXPECT_FALSE(extract("", &a));
-}
-
-
-TEST(ip4mask, body)
-{
- IP4Mask m;
- EXPECT_EQ(IP4Address(), m.addr());
- EXPECT_EQ(IP4Address(), m.mask());
- m = IP4Mask(IP4_LOCALHOST, IP4_BROADCAST);
- EXPECT_EQ(IP4_LOCALHOST, m.addr());
- EXPECT_EQ(IP4_BROADCAST, m.mask());
-}
-
-TEST(ip4mask, str)
-{
- IP4Mask m;
- EXPECT_EQ("0.0.0.0/0.0.0.0", STRNPRINTF(33, "%s", m));
- m = IP4Mask(IP4_LOCALHOST, IP4_BROADCAST);
- EXPECT_EQ("127.0.0.1/255.255.255.255", STRNPRINTF(33, "%s", m));
-}
-
-TEST(ip4mask, extract)
-{
- IP4Mask m;
- EXPECT_FALSE(extract("9.8.7.6/33", &m));
- EXPECT_FALSE(extract("9.8.7.6.5", &m));
- EXPECT_FALSE(extract("9.8.7.6/", &m));
- EXPECT_FALSE(extract("9.8.7", &m));
- EXPECT_FALSE(extract("9.8", &m));
- EXPECT_FALSE(extract("9", &m));
-
- EXPECT_TRUE(extract("127.0.0.1", &m));
- EXPECT_EQ("127.0.0.1/255.255.255.255", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("127.0.0.1.", &m));
- EXPECT_EQ("127.0.0.1/255.255.255.255", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("127.0.0.", &m));
- EXPECT_EQ("127.0.0.0/255.255.255.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("127.0.", &m));
- EXPECT_EQ("127.0.0.0/255.255.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("127.", &m));
- EXPECT_EQ("127.0.0.0/255.0.0.0", STRNPRINTF(32, "%s", m));
-
- EXPECT_TRUE(extract("1.2.3.4/255.255.255.255", &m));
- EXPECT_EQ("1.2.3.4/255.255.255.255", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("1.2.3.0/255.255.255.0", &m));
- EXPECT_EQ("1.2.3.0/255.255.255.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("1.2.0.4/255.255.0.255", &m));
- EXPECT_EQ("1.2.0.4/255.255.0.255", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("1.2.0.0/255.255.0.0", &m));
- EXPECT_EQ("1.2.0.0/255.255.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("1.0.3.4/255.0.255.255", &m));
- EXPECT_EQ("1.0.3.4/255.0.255.255", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("1.0.3.0/255.0.255.0", &m));
- EXPECT_EQ("1.0.3.0/255.0.255.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("1.0.0.4/255.0.0.255", &m));
- EXPECT_EQ("1.0.0.4/255.0.0.255", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("1.0.0.0/255.0.0.0", &m));
- EXPECT_EQ("1.0.0.0/255.0.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.2.3.4/0.255.255.255", &m));
- EXPECT_EQ("0.2.3.4/0.255.255.255", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.2.3.0/0.255.255.0", &m));
- EXPECT_EQ("0.2.3.0/0.255.255.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.2.0.4/0.255.0.255", &m));
- EXPECT_EQ("0.2.0.4/0.255.0.255", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.2.0.0/0.255.0.0", &m));
- EXPECT_EQ("0.2.0.0/0.255.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.3.4/0.0.255.255", &m));
- EXPECT_EQ("0.0.3.4/0.0.255.255", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.3.0/0.0.255.0", &m));
- EXPECT_EQ("0.0.3.0/0.0.255.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.4/0.0.0.255", &m));
- EXPECT_EQ("0.0.0.4/0.0.0.255", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/0.0.0.0", &m));
- EXPECT_EQ("0.0.0.0/0.0.0.0", STRNPRINTF(32, "%s", m));
-
- // please don't do this
- EXPECT_TRUE(extract("120.248.200.217/89.57.126.5", &m));
- EXPECT_EQ("88.56.72.1/89.57.126.5", STRNPRINTF(32, "%s", m));
-
- EXPECT_TRUE(extract("0.0.0.0/32", &m));
- EXPECT_EQ("0.0.0.0/255.255.255.255", STRNPRINTF(32, "%s", m));
-
- EXPECT_TRUE(extract("0.0.0.0/31", &m));
- EXPECT_EQ("0.0.0.0/255.255.255.254", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/30", &m));
- EXPECT_EQ("0.0.0.0/255.255.255.252", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/29", &m));
- EXPECT_EQ("0.0.0.0/255.255.255.248", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/28", &m));
- EXPECT_EQ("0.0.0.0/255.255.255.240", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/27", &m));
- EXPECT_EQ("0.0.0.0/255.255.255.224", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/26", &m));
- EXPECT_EQ("0.0.0.0/255.255.255.192", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/25", &m));
- EXPECT_EQ("0.0.0.0/255.255.255.128", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/24", &m));
- EXPECT_EQ("0.0.0.0/255.255.255.0", STRNPRINTF(32, "%s", m));
-
- EXPECT_TRUE(extract("0.0.0.0/23", &m));
- EXPECT_EQ("0.0.0.0/255.255.254.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/22", &m));
- EXPECT_EQ("0.0.0.0/255.255.252.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/21", &m));
- EXPECT_EQ("0.0.0.0/255.255.248.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/20", &m));
- EXPECT_EQ("0.0.0.0/255.255.240.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/19", &m));
- EXPECT_EQ("0.0.0.0/255.255.224.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/18", &m));
- EXPECT_EQ("0.0.0.0/255.255.192.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/17", &m));
- EXPECT_EQ("0.0.0.0/255.255.128.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/16", &m));
- EXPECT_EQ("0.0.0.0/255.255.0.0", STRNPRINTF(32, "%s", m));
-
- EXPECT_TRUE(extract("0.0.0.0/15", &m));
- EXPECT_EQ("0.0.0.0/255.254.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/14", &m));
- EXPECT_EQ("0.0.0.0/255.252.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/13", &m));
- EXPECT_EQ("0.0.0.0/255.248.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/12", &m));
- EXPECT_EQ("0.0.0.0/255.240.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/11", &m));
- EXPECT_EQ("0.0.0.0/255.224.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/10", &m));
- EXPECT_EQ("0.0.0.0/255.192.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/9", &m));
- EXPECT_EQ("0.0.0.0/255.128.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/8", &m));
- EXPECT_EQ("0.0.0.0/255.0.0.0", STRNPRINTF(32, "%s", m));
-
- EXPECT_TRUE(extract("0.0.0.0/7", &m));
- EXPECT_EQ("0.0.0.0/254.0.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/6", &m));
- EXPECT_EQ("0.0.0.0/252.0.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/5", &m));
- EXPECT_EQ("0.0.0.0/248.0.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/4", &m));
- EXPECT_EQ("0.0.0.0/240.0.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/3", &m));
- EXPECT_EQ("0.0.0.0/224.0.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/2", &m));
- EXPECT_EQ("0.0.0.0/192.0.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/1", &m));
- EXPECT_EQ("0.0.0.0/128.0.0.0", STRNPRINTF(32, "%s", m));
- EXPECT_TRUE(extract("0.0.0.0/0", &m));
- EXPECT_EQ("0.0.0.0/0.0.0.0", STRNPRINTF(32, "%s", m));
-}
-
-TEST(ip4mask, cover)
-{
- IP4Address a;
- IP4Address b = IP4_BROADCAST;
- IP4Address l = IP4_LOCALHOST;
- IP4Address h({127, 255, 255, 255});
- IP4Address p24l({10, 0, 0, 0});
- IP4Address p24h({10, 255, 255, 255});
- IP4Address p20l({172, 16, 0, 0});
- IP4Address p20h({172, 31, 255, 255});
- IP4Address p16l({192, 168, 0, 0});
- IP4Address p16h({192, 168, 255, 255});
- IP4Mask m;
- EXPECT_TRUE(m.covers(a));
- EXPECT_TRUE(m.covers(b));
- EXPECT_TRUE(m.covers(l));
- EXPECT_TRUE(m.covers(h));
- EXPECT_TRUE(m.covers(p24l));
- EXPECT_TRUE(m.covers(p24h));
- EXPECT_TRUE(m.covers(p20l));
- EXPECT_TRUE(m.covers(p20h));
- EXPECT_TRUE(m.covers(p16l));
- EXPECT_TRUE(m.covers(p16h));
- m = IP4Mask(l, a);
- EXPECT_TRUE(m.covers(a));
- EXPECT_TRUE(m.covers(b));
- EXPECT_TRUE(m.covers(l));
- EXPECT_TRUE(m.covers(h));
- EXPECT_TRUE(m.covers(p24l));
- EXPECT_TRUE(m.covers(p24h));
- EXPECT_TRUE(m.covers(p20l));
- EXPECT_TRUE(m.covers(p20h));
- EXPECT_TRUE(m.covers(p16l));
- EXPECT_TRUE(m.covers(p16h));
- m = IP4Mask(l, b);
- EXPECT_FALSE(m.covers(a));
- EXPECT_FALSE(m.covers(b));
- EXPECT_TRUE(m.covers(l));
- EXPECT_FALSE(m.covers(h));
- EXPECT_FALSE(m.covers(p24l));
- EXPECT_FALSE(m.covers(p24h));
- EXPECT_FALSE(m.covers(p20l));
- EXPECT_FALSE(m.covers(p20h));
- EXPECT_FALSE(m.covers(p16l));
- EXPECT_FALSE(m.covers(p16h));
-
- // but the really useful ones are with partial masks
- m = IP4Mask(IP4Address({10, 0, 0, 0}), IP4Address({255, 0, 0, 0}));
- EXPECT_FALSE(m.covers(a));
- EXPECT_FALSE(m.covers(b));
- EXPECT_FALSE(m.covers(l));
- EXPECT_FALSE(m.covers(h));
- EXPECT_TRUE(m.covers(p24l));
- EXPECT_TRUE(m.covers(p24h));
- EXPECT_FALSE(m.covers(p20l));
- EXPECT_FALSE(m.covers(p20h));
- EXPECT_FALSE(m.covers(p16l));
- EXPECT_FALSE(m.covers(p16h));
- EXPECT_FALSE(m.covers(IP4Address({9, 255, 255, 255})));
- EXPECT_FALSE(m.covers(IP4Address({11, 0, 0, 0})));
- m = IP4Mask(IP4Address({127, 0, 0, 0}), IP4Address({255, 0, 0, 0}));
- EXPECT_FALSE(m.covers(a));
- EXPECT_FALSE(m.covers(b));
- EXPECT_TRUE(m.covers(l));
- EXPECT_TRUE(m.covers(h));
- EXPECT_FALSE(m.covers(p24l));
- EXPECT_FALSE(m.covers(p24h));
- EXPECT_FALSE(m.covers(p20l));
- EXPECT_FALSE(m.covers(p20h));
- EXPECT_FALSE(m.covers(p16l));
- EXPECT_FALSE(m.covers(p16h));
- EXPECT_FALSE(m.covers(IP4Address({126, 255, 255, 255})));
- EXPECT_FALSE(m.covers(IP4Address({128, 0, 0, 0})));
- m = IP4Mask(IP4Address({172, 16, 0, 0}), IP4Address({255, 240, 0, 0}));
- EXPECT_FALSE(m.covers(a));
- EXPECT_FALSE(m.covers(b));
- EXPECT_FALSE(m.covers(l));
- EXPECT_FALSE(m.covers(h));
- EXPECT_FALSE(m.covers(p24l));
- EXPECT_FALSE(m.covers(p24h));
- EXPECT_TRUE(m.covers(p20l));
- EXPECT_TRUE(m.covers(p20h));
- EXPECT_FALSE(m.covers(p16l));
- EXPECT_FALSE(m.covers(p16h));
- EXPECT_FALSE(m.covers(IP4Address({172, 15, 255, 255})));
- EXPECT_FALSE(m.covers(IP4Address({172, 32, 0, 0})));
- m = IP4Mask(IP4Address({192, 168, 0, 0}), IP4Address({255, 255, 0, 0}));
- EXPECT_FALSE(m.covers(a));
- EXPECT_FALSE(m.covers(b));
- EXPECT_FALSE(m.covers(l));
- EXPECT_FALSE(m.covers(h));
- EXPECT_FALSE(m.covers(p24l));
- EXPECT_FALSE(m.covers(p24h));
- EXPECT_FALSE(m.covers(p20l));
- EXPECT_FALSE(m.covers(p20h));
- EXPECT_TRUE(m.covers(p16l));
- EXPECT_TRUE(m.covers(p16h));
- EXPECT_FALSE(m.covers(IP4Address({192, 167, 255, 255})));
- EXPECT_FALSE(m.covers(IP4Address({192, 169, 0, 0})));
-
- // OTOH this is crazy
- EXPECT_TRUE(extract("120.248.200.217/89.57.126.5", &m));
- EXPECT_TRUE(m.covers(IP4Address({120, 248, 200, 217})));
- EXPECT_TRUE(m.covers(IP4Address({88, 56, 72, 1})));
- EXPECT_FALSE(m.covers(IP4Address({88, 56, 72, 0})));
- EXPECT_FALSE(m.covers(IP4Address({88, 56, 72, 255})));
-}
diff --git a/src/common/iter.hpp b/src/common/iter.hpp
deleted file mode 100644
index 5b39588..0000000
--- a/src/common/iter.hpp
+++ /dev/null
@@ -1,97 +0,0 @@
-#ifndef TMWA_COMMON_ITER_HPP
-#define TMWA_COMMON_ITER_HPP
-// iter.hpp - tools for dealing with iterators
-//
-// Copyright © 2012-2014 Ben Longbons <b.r.longbons@gmail.com>
-//
-// This file is part of The Mana World (Athena server)
-//
-// This program 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.
-//
-// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
-
-# include "../sanity.hpp"
-
-# include <iterator>
-
-
-/// Simple class to use a pair of iterators with foreach
-template<class It>
-class IteratorPair
-{
- It _b, _e;
-public:
- IteratorPair(It b, It e)
- : _b(b), _e(e)
- {}
-
- It begin() { return _b; }
- It end() { return _e; }
-};
-
-template<class It>
-IteratorPair<It> iterator_pair(It b, It e)
-{
- return {b, e};
-}
-
-template<class T>
-class PassthroughMath
-{
-public:
- static
- T inced(T v) { return ++v; }
-};
-
-// An iterator that just directly contains an integer-like value
-// TODO port this once the new integer API happens
-template<class T, class Math=PassthroughMath<T>>
-class ValueIterator
-{
- T value;
-public:
- typedef std::forward_iterator_tag iterator_category;
- typedef void difference_type;
- typedef T value_type;
- typedef void reference;
- typedef void pointer;
-public:
- ValueIterator(T v)
- : value(v)
- {}
-
- T operator *()
- {
- return value;
- }
- ValueIterator& operator++ ()
- {
- value = Math::inced(value);
- return *this;
- }
- friend bool operator == (ValueIterator l, ValueIterator r)
- {
- return l.value == r.value;
- }
- friend bool operator != (ValueIterator l, ValueIterator r)
- {
- return !(l == r);
- }
-};
-
-template<class T>
-IteratorPair<ValueIterator<T>> value_range(T b, T e)
-{
- return {b, e};
-}
-
-#endif // TMWA_COMMON_ITER_HPP
diff --git a/src/common/iter_test.cpp b/src/common/iter_test.cpp
deleted file mode 100644
index 647ebf9..0000000
--- a/src/common/iter_test.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#include "iter.hpp"
-
-#include <gtest/gtest.h>
-
-#include "../strings/xstring.hpp"
-
-TEST(iterpair, string)
-{
- IteratorPair<ValueIterator<char>> pair = value_range('0', ':');
- const char *str = "0123456789";
- EXPECT_TRUE(std::equal(pair.begin(), pair.end(), str));
-}
-
-TEST(iterpair, signed8)
-{
- IteratorPair<ValueIterator<int8_t>> pair = value_range(int8_t(-128), int8_t(127));
- int8_t arr[255] =
- {
- -128, -127, -126, -125, -124, -123, -122, -121, -120,
- -119, -118, -117, -116, -115, -114, -113, -112, -111, -110,
- -109, -108, -107, -106, -105, -104, -103, -102, -101, -100,
- -99, -98, -97, -96, -95, -94, -93, -92, -91, -90,
- -89, -88, -87, -86, -85, -84, -83, -82, -81, -80,
- -79, -78, -77, -76, -75, -74, -73, -72, -71, -70,
- -69, -68, -67, -66, -65, -64, -63, -62, -61, -60,
- -59, -58, -57, -56, -55, -54, -53, -52, -51, -50,
- -49, -48, -47, -46, -45, -44, -43, -42, -41, -40,
- -39, -38, -37, -36, -35, -34, -33, -32, -31, -30,
- -29, -28, -27, -26, -25, -24, -23, -22, -21, -20,
- -19, -18, -17, -16, -15, -14, -13, -12, -11, -10,
- -9, -8, -7, -6, -5, -4, -3, -2, -1,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
- 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
- 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
- 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
- 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
- 120, 121, 122, 123, 124, 125, 126,
- };
- EXPECT_TRUE(std::equal(pair.begin(), pair.end(), arr + 0));
-}
-
-TEST(iterpair, unsigned8)
-{
- IteratorPair<ValueIterator<uint8_t>> pair = value_range(uint8_t(0), uint8_t(255));
- uint8_t arr[255] =
- {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
- 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
- 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
- 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
- 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
- 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
- 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
- 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
- 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
- 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
- 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
- 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
- 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
- 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
- 220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
- 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
- 240, 241, 242, 243, 244, 245, 246, 247, 248, 249,
- 250, 251, 252, 253, 254,
- };
- EXPECT_TRUE(std::equal(pair.begin(), pair.end(), arr));
-}
diff --git a/src/common/matrix.hpp b/src/common/matrix.hpp
deleted file mode 100644
index 8595191..0000000
--- a/src/common/matrix.hpp
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef TMWA_COMMON_MATRIX_HPP
-#define TMWA_COMMON_MATRIX_HPP
-
-template<class T>
-class Matrix
-{
- std::unique_ptr<T[]> _data;
- size_t _xs, _ys;
-public:
- Matrix()
- : _data()
- , _xs()
- , _ys()
- {}
- Matrix(size_t x, size_t y)
- : _data(new T[x * y]())
- , _xs(x)
- , _ys(y)
- {}
- // no copy-ctor or copy-assign
-
- void reset(size_t x, size_t y)
- {
- *this = Matrix(x, y);
- }
- void clear()
- {
- *this = Matrix();
- }
-
- T& ref(size_t x, size_t y)
- {
- return _data[x + y * _xs];
- }
- const T& ref(size_t x, size_t y) const
- {
- return _data[x + y * _xs];
- }
-
- size_t xs() const
- {
- return _xs;
- }
- size_t ys() const
- {
- return _ys;
- }
-};
-
-#endif // TMWA_COMMON_MATRIX_HPP
diff --git a/src/common/md5calc.cpp b/src/common/md5calc.cpp
deleted file mode 100644
index d23f8e3..0000000
--- a/src/common/md5calc.cpp
+++ /dev/null
@@ -1,352 +0,0 @@
-#include "md5calc.hpp"
-
-#include <cstring>
-
-#include "../strings/xstring.hpp"
-#include "../strings/vstring.hpp"
-
-#include "../io/cxxstdio.hpp"
-#include "../io/read.hpp"
-
-#include "random.hpp"
-#include "utils.hpp"
-
-#include "../poison.hpp"
-
-// auxilary data
-/*
-sin() constant table
-#Reformatted output of:
-echo 'scale=40; obase=16; for (i=1;i<=64;i++) print 2^32 * sin(i), "\n"' |
-bc | sed 's/^-//;s/^/0x/;s/\..*$/,/'
-*/
-static
-const uint32_t T[64] =
-{
- // used by round 1
- 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, //0
- 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, //4
- 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, //8
- 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, //12
- // used by round 2
- 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, //16
- 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, //20
- 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, //24
- 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, //28
- // used by round 3
- 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, //32
- 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, //36
- 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, //40
- 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, //44
- // used by round 4
- 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, //48
- 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, //52
- 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, //56
- 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, //60
-};
-
-// auxilary functions
-// note - the RFC defines these by non-CS conventions: or=v, and=(empty)
-static
-uint32_t rotate_left(uint32_t val, unsigned shift)
-{
- return val << shift | val >> (32 - shift);
-}
-
-static
-uint32_t F(uint32_t X, uint32_t Y, uint32_t Z)
-{
- return (X & Y) | (~X & Z);
-}
-static
-uint32_t G(uint32_t X, uint32_t Y, uint32_t Z)
-{
- return (X & Z) | (Y & ~Z);
-}
-static
-uint32_t H(uint32_t X, uint32_t Y, uint32_t Z)
-{
- return X ^ Y ^ Z;
-}
-static
-uint32_t I(uint32_t X, uint32_t Y, uint32_t Z)
-{
- return Y ^ (X | ~Z);
-}
-
-static
-const struct
-{
- uint8_t k : 4;
- uint8_t : 0;
- uint8_t s : 5;
-// uint8_t i : 6; just increments constantly, from 1 .. 64 over all rounds
-}
-MD5_round1[16] =
-{
- { 0, 7}, { 1, 12}, { 2, 17}, { 3, 22},
- { 4, 7}, { 5, 12}, { 6, 17}, { 7, 22},
- { 8, 7}, { 9, 12}, {10, 17}, {11, 22},
- {12, 7}, {13, 12}, {14, 17}, {15, 22},
-},
-MD5_round2[16] =
-{
- { 1, 5}, { 6, 9}, {11, 14}, { 0, 20},
- { 5, 5}, {10, 9}, {15, 14}, { 4, 20},
- { 9, 5}, {14, 9}, { 3, 14}, { 8, 20},
- {13, 5}, { 2, 9}, { 7, 14}, {12, 20},
-},
-MD5_round3[16] =
-{
- { 5, 4}, { 8, 11}, {11, 16}, {14, 23},
- { 1, 4}, { 4, 11}, { 7, 16}, {10, 23},
- {13, 4}, { 0, 11}, { 3, 16}, { 6, 23},
- { 9, 4}, {12, 11}, {15, 16}, { 2, 23},
-},
-MD5_round4[16] =
-{
- { 0, 6}, { 7, 10}, {14, 15}, { 5, 21},
- {12, 6}, { 3, 10}, {10, 15}, { 1, 21},
- { 8, 6}, {15, 10}, { 6, 15}, {13, 21},
- { 4, 6}, {11, 10}, { 2, 15}, { 9, 21},
-};
-
-
-void MD5_init(MD5_state* state)
-{
- // in the RFC, these are specified as bytes, interpreted as little-endian
- state->val[0] = 0x67452301;
- state->val[1] = 0xEFCDAB89;
- state->val[2] = 0x98BADCFE;
- state->val[3] = 0x10325476;
-}
-
-void MD5_do_block(MD5_state* state, MD5_block block)
-{
-#define X block.data
-#define a state->val[(16 - i) % 4]
-#define b state->val[(17 - i) % 4]
-#define c state->val[(18 - i) % 4]
-#define d state->val[(19 - i) % 4]
- // save the values
- const MD5_state saved = *state;
- // round 1
- for (int i = 0; i < 16; i++)
- {
-#define k MD5_round1[i].k
-#define s MD5_round1[i].s
- a = b + rotate_left(a + F(b, c, d) + X[k] + T[i + 0x0], s);
-#undef k
-#undef s
- }
- // round 2
- for (int i = 0; i < 16; i++)
- {
-#define k MD5_round2[i].k
-#define s MD5_round2[i].s
- a = b + rotate_left(a + G(b, c, d) + X[k] + T[i + 0x10], s);
-#undef k
-#undef s
- }
- // round 3
- for (int i = 0; i < 16; i++)
- {
-#define k MD5_round3[i].k
-#define s MD5_round3[i].s
- a = b + rotate_left(a + H(b, c, d) + X[k] + T[i + 0x20], s);
-#undef k
-#undef s
- }
- // round 4
- for (int i = 0; i < 16; i++)
- {
-#define k MD5_round4[i].k
-#define s MD5_round4[i].s
- a = b + rotate_left(a + I(b, c, d) + X[k] + T[i + 0x30], s);
-#undef k
-#undef s
- }
- // adjust state based on original
- state->val[0] += saved.val[0];
- state->val[1] += saved.val[1];
- state->val[2] += saved.val[2];
- state->val[3] += saved.val[3];
-#undef a
-#undef b
-#undef c
-#undef d
-}
-
-void MD5_to_bin(MD5_state state, md5_binary& out)
-{
- for (int i = 0; i < 0x10; i++)
- out[i] = state.val[i / 4] >> 8 * (i % 4);
-}
-
-static
-const char hex[] = "0123456789abcdef";
-
-void MD5_to_str(MD5_state state, md5_string& out_)
-{
- md5_binary bin;
- MD5_to_bin(state, bin);
- char out[0x20];
- for (int i = 0; i < 0x10; i++)
- out[2 * i] = hex[bin[i] >> 4],
- out[2 * i + 1] = hex[bin[i] & 0xf];
- out_ = stringish<md5_string>(XString(out, out + 0x20, nullptr));
-}
-
-MD5_state MD5_from_string(XString msg)
-{
- MD5_state state;
- MD5_init(&state);
- MD5_block block;
- const uint64_t msg_full_len = msg.size();
- while (msg.size() >= 64)
- {
- for (int i = 0; i < 0x10; i++)
- X[i] = msg[4 * i + 0] | msg[4 * i + 1] << 8 | msg[4 * i + 2] << 16 | msg[4 * i + 3] << 24;
- MD5_do_block(&state, block);
- msg = msg.xslice_t(64);
- }
- // now pad 1-512 bits + the 64-bit length - may be two blocks
- uint8_t buf[0x40] = {};
- really_memcpy(buf, reinterpret_cast<const uint8_t *>(msg.data()), msg.size());
- buf[msg.size()] = 0x80; // a single one bit
- if (64 - msg.size() > 8)
- {
- for (int i = 0; i < 8; i++)
- buf[0x38 + i] = (msg_full_len * 8) >> (i * 8);
- }
- for (int i = 0; i < 0x10; i++)
- X[i] = buf[4 * i + 0] | buf[4 * i + 1] << 8 | buf[4 * i + 2] << 16 | buf[4 * i + 3] << 24;
- MD5_do_block(&state, block);
- if (64 - msg.size() <= 8)
- {
- really_memset0(buf, 0x38);
- for (int i = 0; i < 8; i++)
- buf[0x38 + i] = (msg_full_len * 8) >> (i * 8);
- for (int i = 0; i < 0x10; i++)
- X[i] = buf[4 * i + 0] | buf[4 * i + 1] << 8 | buf[4 * i + 2] << 16 | buf[4 * i + 3] << 24;
- MD5_do_block(&state, block);
- }
- return state;
-}
-
-// TODO - refactor MD5 into a stream, and merge the implementations
-// I once implemented an ostream that does it ...
-MD5_state MD5_from_FILE(io::ReadFile& in)
-{
- uint64_t total_len = 0;
-
- uint8_t buf[0x40];
- uint8_t block_len = 0;
-
- MD5_state state;
- MD5_init(&state);
-
- MD5_block block;
-
- while (true)
- {
- size_t rv = in.get(sign_cast<char *>(buf + block_len), 0x40 - block_len);
- if (!rv)
- break;
- total_len += 8 * rv; // in bits
- block_len += rv;
- if (block_len != 0x40)
- continue;
- for (int i = 0; i < 0x10; i++)
- X[i] = buf[4 * i + 0] | buf[4 * i + 1] << 8 | buf[4 * i + 2] << 16 | buf[4 * i + 3] << 24;
- MD5_do_block(&state, block);
- block_len = 0;
- }
- // no more input, just pad and append the length
- buf[block_len] = 0x80;
- really_memset0(buf + block_len + 1, 0x40 - block_len - 1);
- if (block_len < 0x38)
- {
- for (int i = 0; i < 8; i++)
- buf[0x38 + i] = total_len >> i * 8;
- }
- for (int i = 0; i < 0x10; i++)
- X[i] = buf[4 * i + 0] | buf[4 * i + 1] << 8 | buf[4 * i + 2] << 16 | buf[4 * i + 3] << 24;
- MD5_do_block(&state, block);
- if (0x38 <= block_len)
- {
- really_memset0(buf, 0x38);
- for (int i = 0; i < 8; i++)
- buf[0x38 + i] = total_len >> i * 8;
- for (int i = 0; i < 0x10; i++)
- X[i] = buf[4 * i + 0] | buf[4 * i + 1] << 8 | buf[4 * i + 2] << 16 | buf[4 * i + 3] << 24;
- MD5_do_block(&state, block);
- }
- return state;
-}
-
-
-// Hash a password with a salt.
-// Whoever wrote this FAILS programming
-AccountCrypt MD5_saltcrypt(AccountPass key, SaltString salt)
-{
- char cbuf[64] {};
-
- // hash the key then the salt
- // buf ends up as a 64-char NUL-terminated string
- md5_string tbuf, tbuf2;
- MD5_to_str(MD5_from_string(key), tbuf);
- MD5_to_str(MD5_from_string(salt), tbuf2);
- const auto it = std::copy(tbuf.begin(), tbuf.end(), std::begin(cbuf));
- auto it2 = std::copy(tbuf2.begin(), tbuf2.end(), it);
- assert(it2 == std::end(cbuf));
-
- md5_string tbuf3;
- MD5_to_str(MD5_from_string(XString(std::begin(cbuf), it2, nullptr)), tbuf3);
-
- VString<31> obuf;
-
- // This truncates the string, but we have to keep it like that for compatibility
- SNPRINTF(obuf, 32, "!%s$%s", salt, tbuf3);
- return stringish<AccountCrypt>(obuf);
-}
-
-SaltString make_salt(void)
-{
- char salt[5];
- for (int i = 0; i < 5; i++)
- // 126 would probably actually be okay
- salt[i] = random_::in(48, 125);
- return stringish<SaltString>(XString(salt + 0, salt + 5, nullptr));
-}
-
-bool pass_ok(AccountPass password, AccountCrypt crypted)
-{
- // crypted is like !salt$hash
- auto begin = crypted.begin() + 1;
- auto end = std::find(begin, crypted.end(), '$');
- SaltString salt = stringish<SaltString>(crypted.xislice(begin, end));
-
- return crypted == MD5_saltcrypt(password, salt);
-}
-
-// [M|h]ashes up an IP address and a secret key
-// to return a hopefully unique masked IP.
-IP4Address MD5_ip(IP4Address ip)
-{
- static SaltString secret = make_salt();
-
- // MD5sum a secret + the IP address
- VString<31> ipbuf;
- SNPRINTF(ipbuf, 32, "%s %s", ip, secret);
- md5_binary obuf;
- MD5_to_bin(MD5_from_string(ipbuf), obuf);
-
- // Fold the md5sum to 32 bits, pack the bytes to an in_addr
- return IP4Address({
- static_cast<uint8_t>(obuf[0] ^ obuf[1] ^ obuf[8] ^ obuf[9]),
- static_cast<uint8_t>(obuf[2] ^ obuf[3] ^ obuf[10] ^ obuf[11]),
- static_cast<uint8_t>(obuf[4] ^ obuf[5] ^ obuf[12] ^ obuf[13]),
- static_cast<uint8_t>(obuf[6] ^ obuf[7] ^ obuf[14] ^ obuf[15]),
- });
-}
diff --git a/src/common/md5calc.hpp b/src/common/md5calc.hpp
deleted file mode 100644
index 45bec84..0000000
--- a/src/common/md5calc.hpp
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef MD5CALC_HPP
-#define MD5CALC_HPP
-
-# include "../sanity.hpp"
-
-# include <netinet/in.h>
-
-# include <cstdint>
-# include <cstddef>
-# include <cstdio>
-
-# include <array>
-
-# include "../strings/fwd.hpp"
-# include "../strings/vstring.hpp"
-
-# include "../io/fwd.hpp"
-
-# include "ip.hpp"
-# include "mmo.hpp"
-
-/// The digest state - becomes the output
-struct MD5_state
-{
- // classically named {A,B,C,D}
- // but use an so we can index
- uint32_t val[4];
-};
-struct MD5_block
-{
- uint32_t data[16];
-};
-
-struct md5_binary : std::array<uint8_t, 0x10> {};
-struct md5_string : VString<0x20> {};
-struct SaltString : VString<5> {};
-
-// Implementation
-void MD5_init(MD5_state *state);
-void MD5_do_block(MD5_state *state, MD5_block block);
-
-// Output formatting
-void MD5_to_bin(MD5_state state, md5_binary& out);
-void MD5_to_str(MD5_state state, md5_string& out);
-
-// Convenience
-MD5_state MD5_from_string(XString msg);
-MD5_state MD5_from_FILE(io::ReadFile& in);
-
-
-// whoever wrote this fails basic understanding of
-AccountCrypt MD5_saltcrypt(AccountPass key, SaltString salt);
-
-/// return some random characters (statically allocated)
-// Currently, returns a 5-char string
-SaltString make_salt(void);
-
-/// check plaintext password against saved saltcrypt
-bool pass_ok(AccountPass password, AccountCrypt crypted);
-
-/// This returns an IP4Address because it is configurable whether it gets called at all
-IP4Address MD5_ip(IP4Address ip);
-
-#endif // MD5CALC_HPP
diff --git a/src/common/md5calc_test.cpp b/src/common/md5calc_test.cpp
deleted file mode 100644
index ab5f242..0000000
--- a/src/common/md5calc_test.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#include "md5calc.hpp"
-
-#include <gtest/gtest.h>
-
-#include "../strings/xstring.hpp"
-#include "../strings/vstring.hpp"
-
-#include "utils.hpp"
-
-// This should be made part of the main API,
-// but is not yet to keep the diff small.
-// Edit: hack to fix the new strict comparison.
-static
-VString<32> MD5(XString in)
-{
- md5_string out;
- MD5_to_str(MD5_from_string(in), out);
- return out;
-}
-
-TEST(md5calc, rfc1321)
-{
- EXPECT_EQ("d41d8cd98f00b204e9800998ecf8427e", MD5(""));
- EXPECT_EQ("0cc175b9c0f1b6a831c399e269772661", MD5("a"));
- EXPECT_EQ("900150983cd24fb0d6963f7d28e17f72", MD5("abc"));
- EXPECT_EQ("f96b697d7cb7938d525a2f31aaf161d0", MD5("message digest"));
- EXPECT_EQ("c3fcd3d76192e4007dfb496cca67e13b", MD5("abcdefghijklmnopqrstuvwxyz"));
- EXPECT_EQ("d174ab98d277d9f5a5611c2c9f419d9f", MD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"));
- EXPECT_EQ("57edf4a22be3c955ac49da2e2107b67a", MD5("12345678901234567890123456789012345678901234567890123456789012345678901234567890"));
-}
diff --git a/src/common/mmo.hpp b/src/common/mmo.hpp
deleted file mode 100644
index bb30682..0000000
--- a/src/common/mmo.hpp
+++ /dev/null
@@ -1,380 +0,0 @@
-/// Global structures and defines
-#ifndef MMO_HPP
-#define MMO_HPP
-
-# include "../sanity.hpp"
-
-# include "../strings/vstring.hpp"
-
-# include "timer.t.hpp"
-# include "utils2.hpp"
-
-// affects CharName
-# define NAME_IGNORING_CASE 1
-
-constexpr int FIFOSIZE_SERVERLINK = 256 * 1024;
-
-constexpr int MAX_MAP_PER_SERVER = 512;
-constexpr int MAX_INVENTORY = 100;
-constexpr int MAX_AMOUNT = 30000;
-constexpr int MAX_ZENY = 1000000000; // 1G zeny
-
-enum class SkillID : uint16_t;
-constexpr SkillID MAX_SKILL = SkillID(474); // not 450
-constexpr SkillID get_enum_min_value(SkillID) { return SkillID(); }
-constexpr SkillID get_enum_max_value(SkillID) { return MAX_SKILL; }
-
-constexpr int GLOBAL_REG_NUM = 96;
-constexpr int ACCOUNT_REG_NUM = 16;
-constexpr int ACCOUNT_REG2_NUM = 16;
-constexpr interval_t DEFAULT_WALK_SPEED = std::chrono::milliseconds(150);
-constexpr interval_t MIN_WALK_SPEED = interval_t::zero();
-constexpr interval_t MAX_WALK_SPEED = std::chrono::seconds(1);
-constexpr int MAX_STORAGE = 300;
-constexpr int MAX_PARTY = 12;
-
-# define MIN_HAIR_STYLE battle_config.min_hair_style
-# define MAX_HAIR_STYLE battle_config.max_hair_style
-# define MIN_HAIR_COLOR battle_config.min_hair_color
-# define MAX_HAIR_COLOR battle_config.max_hair_color
-# define MIN_CLOTH_COLOR battle_config.min_cloth_color
-# define MAX_CLOTH_COLOR battle_config.max_cloth_color
-
-struct AccountName : VString<23> {};
-struct AccountPass : VString<23> {};
-struct AccountCrypt : VString<39> {};
-struct AccountEmail : VString<39> {};
-struct ServerName : VString<19> {};
-struct PartyName : VString<23> {};
-struct VarName : VString<31> {};
-template<class T>
-T stringish(VString<sizeof(T) - 1> iv)
-{
- T rv;
- static_cast<VString<sizeof(T) - 1>&>(rv) = iv;
- return rv;
-}
-# define DEFAULT_EMAIL stringish<AccountEmail>("a@a.com")
-
-// It is decreed: a mapname shall not contain an extension
-class MapName : public strings::_crtp_string<MapName, MapName, strings::ZPair>
-{
- VString<15> _impl;
-public:
- MapName() = default;
- MapName(VString<15> v) : _impl(v.xislice_h(std::find(v.begin(), v.end(), '.'))) {}
-
- iterator begin() const { return &*_impl.begin(); }
- iterator end() const { return &*_impl.end(); }
- const char *c_str() const { return _impl.c_str(); }
-
- operator RString() const { return _impl; }
- operator AString() const { return _impl; }
- operator TString() const { return _impl; }
- operator SString() const { return _impl; }
- operator ZString() const { return _impl; }
- operator XString() const { return _impl; }
-};
-template<>
-inline
-MapName stringish<MapName>(VString<15> iv)
-{
- return iv;
-}
-inline
-const char *decay_for_printf(const MapName& vs) { return vs.c_str(); }
-
-// It is decreed: a charname is sometimes case sensitive
-struct CharName
-{
-private:
- VString<23> _impl;
-public:
- CharName() = default;
- explicit CharName(VString<23> name)
- : _impl(name)
- {}
-
- VString<23> to__actual() const
- {
- return _impl;
- }
- VString<23> to__lower() const
- {
- return _impl.to_lower();
- }
- VString<23> to__upper() const
- {
- return _impl.to_upper();
- }
- VString<23> to__canonical() const
- {
-# if NAME_IGNORING_CASE == 0
- return to__actual();
-# endif
-# if NAME_IGNORING_CASE == 1
- return to__lower();
-# endif
- }
-
- friend bool operator == (const CharName& l, const CharName& r)
- { return l.to__canonical() == r.to__canonical(); }
- friend bool operator != (const CharName& l, const CharName& r)
- { return l.to__canonical() != r.to__canonical(); }
- friend bool operator < (const CharName& l, const CharName& r)
- { return l.to__canonical() < r.to__canonical(); }
- friend bool operator <= (const CharName& l, const CharName& r)
- { return l.to__canonical() <= r.to__canonical(); }
- friend bool operator > (const CharName& l, const CharName& r)
- { return l.to__canonical() > r.to__canonical(); }
- friend bool operator >= (const CharName& l, const CharName& r)
- { return l.to__canonical() >= r.to__canonical(); }
-
- friend
- VString<23> convert_for_printf(const CharName& vs) { return vs.to__actual(); }
-};
-template<>
-inline
-CharName stringish<CharName>(VString<23> iv)
-{
- return CharName(iv);
-}
-
-namespace e
-{
-enum class EPOS : uint16_t
-{
- ZERO = 0x0000,
-
- LEGS = 0x0001,
- WEAPON = 0x0002,
- GLOVES = 0x0004,
- CAPE = 0x0008,
- MISC1 = 0x0010,
- SHIELD = 0x0020,
- SHOES = 0x0040,
- MISC2 = 0x0080,
- HAT = 0x0100,
- TORSO = 0x0200,
-
- ARROW = 0x8000,
-};
-ENUM_BITWISE_OPERATORS(EPOS)
-
-constexpr EPOS get_enum_min_value(EPOS) { return EPOS(0x0000); }
-constexpr EPOS get_enum_max_value(EPOS) { return EPOS(0xffff); }
-}
-using e::EPOS;
-
-struct item
-{
- int id;
- short nameid;
- short amount;
- EPOS equip;
-};
-
-struct point
-{
- MapName map_;
- short x, y;
-};
-
-namespace e
-{
-enum class SkillFlags : uint16_t;
-}
-using e::SkillFlags;
-
-struct skill_value
-{
- unsigned short lv;
- SkillFlags flags;
-
- friend bool operator == (const skill_value& l, const skill_value& r)
- {
- return l.lv == r.lv && l.flags == r.flags;
- }
- friend bool operator != (const skill_value& l, const skill_value& r)
- {
- return !(l == r);
- }
-};
-
-struct global_reg
-{
- VarName str;
- int value;
-};
-
-// Option and Opt1..3 in map.hpp
-namespace e
-{
-enum class Option : uint16_t;
-constexpr Option get_enum_min_value(Option) { return Option(0x0000); }
-constexpr Option get_enum_max_value(Option) { return Option(0xffff); }
-}
-using e::Option;
-
-enum class ATTR
-{
- STR = 0,
- AGI = 1,
- VIT = 2,
- INT = 3,
- DEX = 4,
- LUK = 5,
-
- COUNT = 6,
-};
-
-constexpr ATTR ATTRs[6] =
-{
- ATTR::STR,
- ATTR::AGI,
- ATTR::VIT,
- ATTR::INT,
- ATTR::DEX,
- ATTR::LUK,
-};
-
-enum class ItemLook : uint16_t
-{
- NONE = 0,
- BLADE = 1, // or some other common weapons
- _2,
- SETZER_AND_SCYTHE = 3,
- _6,
- STAFF = 10,
- BOW = 11,
- _13 = 13,
- _14 = 14,
- _16 = 16,
- SINGLE_HANDED_COUNT = 17,
-
- DUAL_BLADE = 0x11,
- DUAL_2 = 0x12,
- DUAL_6 = 0x13,
- DUAL_12 = 0x14,
- DUAL_16 = 0x15,
- DUAL_26 = 0x16,
-};
-
-enum class SEX : uint8_t
-{
- FEMALE = 0,
- MALE = 1,
- // For items. This is also used as error, sometime.
- NEUTRAL = 2,
-};
-inline
-char sex_to_char(SEX sex)
-{
- switch (sex)
- {
- case SEX::FEMALE: return 'F';
- case SEX::MALE: return 'M';
- default: return '\0';
- }
-}
-inline
-SEX sex_from_char(char c)
-{
- switch (c)
- {
- case 'F': return SEX::FEMALE;
- case 'M': return SEX::MALE;
- default: return SEX::NEUTRAL;
- }
-}
-
-struct CharKey
-{
- CharName name;
- int account_id;
- int char_id;
- unsigned char char_num;
-};
-
-struct CharData
-{
- int partner_id;
-
- int base_exp, job_exp, zeny;
-
- short species;
- short status_point, skill_point;
- int hp, max_hp, sp, max_sp;
- Option option;
- short karma, manner;
- short hair, hair_color, clothes_color;
- int party_id;
-
- ItemLook weapon;
- short shield;
- short head_top, head_mid, head_bottom;
-
- unsigned char base_level, job_level;
- earray<short, ATTR, ATTR::COUNT> attrs;
- SEX sex;
-
- unsigned long mapip;
- unsigned int mapport;
-
- struct point last_point, save_point;
- struct item inventory[MAX_INVENTORY];
- earray<skill_value, SkillID, MAX_SKILL> skill;
- int global_reg_num;
- struct global_reg global_reg[GLOBAL_REG_NUM];
- int account_reg_num;
- struct global_reg account_reg[ACCOUNT_REG_NUM];
- int account_reg2_num;
- struct global_reg account_reg2[ACCOUNT_REG2_NUM];
-};
-
-struct CharPair
-{
- CharKey key;
- std::unique_ptr<CharData> data;
-
- CharPair()
- : key{}, data(make_unique<CharData>())
- {}
-};
-
-struct storage
-{
- int dirty;
- int account_id;
- short storage_status;
- short storage_amount;
- struct item storage_[MAX_STORAGE];
-};
-
-struct map_session_data;
-
-struct GM_Account
-{
- int account_id;
- uint8_t level;
-};
-
-struct party_member
-{
- int account_id;
- CharName name;
- MapName map;
- int leader, online, lv;
- struct map_session_data *sd;
-};
-
-struct party
-{
- int party_id;
- PartyName name;
- int exp;
- int item;
- struct party_member member[MAX_PARTY];
-};
-
-#endif // MMO_HPP
diff --git a/src/common/nullpo.cpp b/src/common/nullpo.cpp
deleted file mode 100644
index 423ed8c..0000000
--- a/src/common/nullpo.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "nullpo.hpp"
-
-#include <cstdio>
-
-#include "../poison.hpp"
-
-/// Actual output function
-static
-void nullpo_info(const char *file, int line, const char *func)
-{
- if (!file)
- file = "??";
- if (!func || !*func)
- func = "unknown";
-
- fprintf(stderr, "%s:%d: in func `%s': NULL pointer\n",
- file, line, func);
-}
-
-bool nullpo_chk(const char *file, int line, const char *func,
- const void *target)
-{
- if (target)
- return 0;
-
- nullpo_info(file, line, func);
- return 1;
-}
diff --git a/src/common/nullpo.hpp b/src/common/nullpo.hpp
deleted file mode 100644
index 0eaa1b2..0000000
--- a/src/common/nullpo.hpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/// return wrappers for unexpected NULL pointers
-#ifndef NULLPO_HPP
-#define NULLPO_HPP
-/// Uncomment this to live dangerously
-/// (really exist to detect mostly-unused variables)
-//# define BUG_FREE
-
-/// All functions print to standard error (was: standard output)
-/// nullpo_ret(cond) - return 0 if given pointer is NULL
-/// nullpo_retv(cond) - just return (function returns void)
-/// nullpo_retr(rv, cond) - return given value instead
-
-# ifndef BUG_FREE
-# define nullpo_retr(ret, t) \
- if (nullpo_chk(__FILE__, __LINE__, __PRETTY_FUNCTION__, t)) \
- return ret;
-# else // BUG_FREE
-# define nullpo_retr(ret, t) /*t*/
-# endif // BUG_FREE
-
-# define nullpo_ret(t) nullpo_retr(0, t)
-# define nullpo_retv(t) nullpo_retr(, t)
-
-# include "../sanity.hpp"
-
-/// Used by macros in this header
-bool nullpo_chk(const char *file, int line, const char *func,
- const void *target);
-
-template<class T>
-bool nullpo_chk(const char *file, int line, const char *func, T target)
-{
- return nullpo_chk(file, line, func, target.operator->());
-}
-template<class T>
-bool nullpo_chk(const char *file, int line, const char *func, T *target)
-{
- return nullpo_chk(file, line, func, static_cast<const void *>(target));
-}
-
-#endif // NULLPO_HPP
diff --git a/src/common/operators.hpp b/src/common/operators.hpp
deleted file mode 100644
index 3d44b81..0000000
--- a/src/common/operators.hpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef OPERATORS_HPP
-#define OPERATORS_HPP
-
-namespace _operators
-{
- class Comparable {};
-
- template<class T>
- bool operator == (T l, T r)
- {
- return l.value == r.value;
- }
-
- template<class T>
- bool operator != (T l, T r)
- {
- return l.value != r.value;
- }
-
- template<class T>
- bool operator < (T l, T r)
- {
- return l.value < r.value;
- }
-
- template<class T>
- bool operator <= (T l, T r)
- {
- return l.value <= r.value;
- }
-
- template<class T>
- bool operator > (T l, T r)
- {
- return l.value > r.value;
- }
-
- template<class T>
- bool operator >= (T l, T r)
- {
- return l.value >= r.value;
- }
-}
-
-using _operators::Comparable;
-
-#endif // OPERATORS_HPP
diff --git a/src/common/random.cpp b/src/common/random.cpp
deleted file mode 100644
index 273dcec..0000000
--- a/src/common/random.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "random2.hpp"
-
-#include "../poison.hpp"
-
-namespace random_
-{
- std::mt19937 generate{std::random_device()()};
-} // namespace random_
diff --git a/src/common/random.hpp b/src/common/random.hpp
deleted file mode 100644
index a694cce..0000000
--- a/src/common/random.hpp
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef RANDOM_HPP
-#define RANDOM_HPP
-
-# include "random.t.hpp"
-
-# include "../sanity.hpp"
-
-# include <random>
-
-// This is not namespace random since that collides with a C function,
-// but this can be revisited when everything goes into namespace tmwa.
-namespace random_
-{
- /// Get a random number from 0 .. 2**32 - 1
- extern std::mt19937 generate;
-
- /// Get a random number from 0 .. bound - 1
- inline
- int to(int bound)
- {
- std::uniform_int_distribution<int> dist(0, bound - 1);
- return dist(generate);
- }
-
- /// Get a random number from low .. high (inclusive!)
- inline
- int in(int low, int high)
- {
- std::uniform_int_distribution<int> dist(low, high);
- return dist(generate);
- }
-
- inline
- bool coin()
- {
- // sigh, can't specify <bool> directly ...
- std::uniform_int_distribution<int> dist(false, true);
- return dist(generate);
- }
-
- inline
- bool chance(Fraction f)
- {
- if (f.num <= 0)
- return false;
- if (f.num >= f.den)
- return true;
- return random_::to(f.den) < f.num;
- }
-
- // C is usually one of:
- // std::vector<T>
- // std::initializer_list<T>
- // std::array<T, n>
- template<class C>
- auto choice(C&& c) -> decltype(*c.begin())
- {
- return *(c.begin() + random_::to(c.size()));
- }
-
- // allow bare braces
- template<class T>
- T choice(std::initializer_list<T>&& il)
- {
- return random_::choice(il);
- }
-} // namespace random_
-
-#endif // RANDOM_HPP
diff --git a/src/common/random.t.hpp b/src/common/random.t.hpp
deleted file mode 100644
index 98a6c59..0000000
--- a/src/common/random.t.hpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef RANDOM_T_HPP
-#define RANDOM_T_HPP
-
-namespace random_
-{
- struct Fraction
- {
- int num, den;
- };
-
- template<class T, T den>
- struct Fixed
- {
- T num;
-
- operator Fraction()
- {
- return {num, den};
- }
- };
-} // namespace random_
-
-#endif // RANDOM_T_HPP
diff --git a/src/common/random2.hpp b/src/common/random2.hpp
deleted file mode 100644
index 86deddf..0000000
--- a/src/common/random2.hpp
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef RANDOM2_HPP
-#define RANDOM2_HPP
-
-# include "random.hpp"
-# include "utils2.hpp"
-
-# include <algorithm>
-
-namespace random_
-{
- namespace detail
- {
- struct RandomIterator
- {
- int bound;
- int current;
- bool frist;
-
- void operator ++()
- {
- frist = false;
- // TODO: reimplement in terms of LFSRs, so that certain
- // blockage patterns don't favor adjacent cells.
- current = current + 1;
- if (current == bound)
- current = 0;
- }
- int operator *()
- {
- return current;
- }
- };
-
- inline
- bool operator == (RandomIterator l, RandomIterator r)
- {
- return l.current == r.current && l.frist == r.frist;
- }
-
- inline
- bool operator != (RandomIterator l, RandomIterator r)
- {
- return !(l == r);
- }
- }
-
- /// Yield every cell from 0 .. bound - 1 in some order.
- /// The starting position is random, but not the order itself.
- ///
- /// Expected usage:
- /// for (int i : random_::iterator(vec.size()))
- /// if (vec[i].okay())
- /// return frob(vec[i]);
- inline
- IteratorPair<detail::RandomIterator> iterator(int bound)
- {
- int current = random_::to(bound);
- return
- {
- detail::RandomIterator{bound, current, true},
- detail::RandomIterator{bound, current, false}
- };
- }
-
- /// similar to std::random_shuffle(c.begin(), c.end()), but guaranteed
- /// to use a good source of randomness.
- template<class C>
- void shuffle(C&& c)
- {
- std::random_shuffle(c.begin(), c.end(), random_::to);
- }
-} // namespace random_
-
-#endif // RANDOM2_HPP
diff --git a/src/common/socket.cpp b/src/common/socket.cpp
deleted file mode 100644
index 73e32a4..0000000
--- a/src/common/socket.cpp
+++ /dev/null
@@ -1,474 +0,0 @@
-#include "socket.hpp"
-
-#include <arpa/inet.h>
-#include <netinet/tcp.h>
-#include <sys/socket.h>
-//#include <sys/types.h>
-
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <cstdlib>
-#include <cstring>
-#include <ctime>
-
-#include "../io/cxxstdio.hpp"
-#include "core.hpp"
-#include "timer.hpp"
-#include "utils.hpp"
-
-#include "../poison.hpp"
-
-static
-io::FD_Set readfds;
-static
-int fd_max;
-
-static
-const uint32_t RFIFO_SIZE = 65536;
-static
-const uint32_t WFIFO_SIZE = 65536;
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wold-style-cast"
-static
-std::array<std::unique_ptr<Session>, FD_SETSIZE> session;
-#pragma GCC diagnostic pop
-
-void set_session(io::FD fd, std::unique_ptr<Session> sess)
-{
- int f = fd.uncast_dammit();
- assert (0 <= f && f < FD_SETSIZE);
- session[f] = std::move(sess);
-}
-Session *get_session(io::FD fd)
-{
- int f = fd.uncast_dammit();
- if (0 <= f && f < FD_SETSIZE)
- return session[f].get();
- return nullptr;
-}
-void reset_session(io::FD fd)
-{
- int f = fd.uncast_dammit();
- assert (0 <= f && f < FD_SETSIZE);
- session[f] = nullptr;
-}
-int get_fd_max() { return fd_max; }
-IteratorPair<ValueIterator<io::FD, IncrFD>> iter_fds()
-{
- return {io::FD::cast_dammit(0), io::FD::cast_dammit(fd_max)};
-}
-
-/// clean up by discarding handled bytes
-inline
-void RFIFOFLUSH(Session *s)
-{
- really_memmove(&s->rdata[0], &s->rdata[s->rdata_pos], RFIFOREST(s));
- s->rdata_size = RFIFOREST(s);
- s->rdata_pos = 0;
-}
-
-/// how much room there is to read more data
-inline
-size_t RFIFOSPACE(Session *s)
-{
- return s->max_rdata - s->rdata_size;
-}
-
-
-/// Discard all input
-static
-void null_parse(Session *s);
-/// Default parser for new connections
-static
-void (*default_func_parse)(Session *) = null_parse;
-
-void set_defaultparse(void (*defaultparse)(Session *))
-{
- default_func_parse = defaultparse;
-}
-
-/// Read from socket to the queue
-static
-void recv_to_fifo(Session *s)
-{
- if (s->eof)
- return;
-
- ssize_t len = s->fd.read(&s->rdata[s->rdata_size],
- RFIFOSPACE(s));
-
- if (len > 0)
- {
- s->rdata_size += len;
- s->connected = 1;
- }
- else
- {
- s->eof = 1;
- }
-}
-
-static
-void send_from_fifo(Session *s)
-{
- if (s->eof)
- return;
-
- ssize_t len = s->fd.write(&s->wdata[0], s->wdata_size);
-
- if (len > 0)
- {
- s->wdata_size -= len;
- if (s->wdata_size)
- {
- really_memmove(&s->wdata[0], &s->wdata[len],
- s->wdata_size);
- }
- s->connected = 1;
- }
- else
- {
- s->eof = 1;
- }
-}
-
-static
-void null_parse(Session *s)
-{
- PRINTF("null_parse : %d\n", s);
- RFIFOSKIP(s, RFIFOREST(s));
-}
-
-
-static
-void connect_client(Session *ls)
-{
- struct sockaddr_in client_address;
- socklen_t len = sizeof(client_address);
-
- io::FD fd = ls->fd.accept(reinterpret_cast<struct sockaddr *>(&client_address), &len);
- if (fd == io::FD())
- {
- perror("accept");
- return;
- }
- if (fd.uncast_dammit() >= SOFT_LIMIT)
- {
- FPRINTF(stderr, "softlimit reached, disconnecting : %d\n", fd.uncast_dammit());
- fd.shutdown(SHUT_RDWR);
- fd.close();
- return;
- }
- if (fd_max <= fd.uncast_dammit())
- {
- fd_max = fd.uncast_dammit() + 1;
- }
-
- const int yes = 1;
- /// Allow to bind() again after the server restarts.
- // Since the socket is still in the TIME_WAIT, there's a possibility
- // that formerly lost packets might be delivered and confuse the server.
- fd.setsockopt(SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
- /// Send packets as soon as possible
- /// even if the kernel thinks there is too little for it to be worth it!
- /// Testing shows this is indeed a good idea.
- fd.setsockopt(IPPROTO_TCP, TCP_NODELAY, &yes, sizeof yes);
-
- // Linux-ism: Set socket options to optimize for thin streams
- // See http://lwn.net/Articles/308919/ and
- // Documentation/networking/tcp-thin.txt .. Kernel 3.2+
-#ifdef TCP_THIN_LINEAR_TIMEOUTS
- fd.setsockopt(IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, &yes, sizeof yes);
-#endif
-#ifdef TCP_THIN_DUPACK
- fd.setsockopt(IPPROTO_TCP, TCP_THIN_DUPACK, &yes, sizeof yes);
-#endif
-
- readfds.set(fd);
-
- fd.fcntl(F_SETFL, O_NONBLOCK);
-
- set_session(fd, make_unique<Session>());
- Session *s = get_session(fd);
- s->fd = fd;
- s->rdata.new_(RFIFO_SIZE);
- s->wdata.new_(WFIFO_SIZE);
-
- s->max_rdata = RFIFO_SIZE;
- s->max_wdata = WFIFO_SIZE;
- s->func_recv = recv_to_fifo;
- s->func_send = send_from_fifo;
- s->func_parse = default_func_parse;
- s->client_ip = IP4Address(client_address.sin_addr);
- s->created = TimeT::now();
- s->connected = 0;
-}
-
-Session *make_listen_port(uint16_t port)
-{
- struct sockaddr_in server_address;
- io::FD fd = io::FD::socket(AF_INET, SOCK_STREAM, 0);
- if (fd == io::FD())
- {
- perror("socket");
- return nullptr;
- }
- if (fd_max <= fd.uncast_dammit())
- fd_max = fd.uncast_dammit() + 1;
-
- fd.fcntl(F_SETFL, O_NONBLOCK);
-
- const int yes = 1;
- /// Allow to bind() again after the server restarts.
- // Since the socket is still in the TIME_WAIT, there's a possibility
- // that formerly lost packets might be delivered and confuse the server.
- fd.setsockopt(SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
- /// Send packets as soon as possible
- /// even if the kernel thinks there is too little for it to be worth it!
- // I'm not convinced this is a good idea; although in minimizes the
- // latency for an individual write, it increases traffic in general.
- fd.setsockopt(IPPROTO_TCP, TCP_NODELAY, &yes, sizeof yes);
-
- server_address.sin_family = AF_INET;
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wold-style-cast"
-#if __GNUC__ > 4 || __GNUC_MINOR__ >= 8
-# pragma GCC diagnostic ignored "-Wuseless-cast"
-#endif
- server_address.sin_addr.s_addr = htonl(INADDR_ANY);
- server_address.sin_port = htons(port);
-#pragma GCC diagnostic pop
-
- if (fd.bind(reinterpret_cast<struct sockaddr *>(&server_address),
- sizeof(server_address)) == -1)
- {
- perror("bind");
- exit(1);
- }
- if (fd.listen(5) == -1)
- { /* error */
- perror("listen");
- exit(1);
- }
-
- readfds.set(fd);
-
- set_session(fd, make_unique<Session>());
- Session *s = get_session(fd);
- s->fd = fd;
-
- s->func_recv = connect_client;
- s->created = TimeT::now();
- s->connected = 1;
-
- return s;
-}
-
-Session *make_connection(IP4Address ip, uint16_t port)
-{
- struct sockaddr_in server_address;
- io::FD fd = io::FD::socket(AF_INET, SOCK_STREAM, 0);
- if (fd == io::FD())
- {
- perror("socket");
- return nullptr;
- }
- if (fd_max <= fd.uncast_dammit())
- fd_max = fd.uncast_dammit() + 1;
-
- const int yes = 1;
- /// Allow to bind() again after the server restarts.
- // Since the socket is still in the TIME_WAIT, there's a possibility
- // that formerly lost packets might be delivered and confuse the server.
- fd.setsockopt(SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
- /// Send packets as soon as possible
- /// even if the kernel thinks there is too little for it to be worth it!
- // I'm not convinced this is a good idea; although in minimizes the
- // latency for an individual write, it increases traffic in general.
- fd.setsockopt(IPPROTO_TCP, TCP_NODELAY, &yes, sizeof yes);
-
- server_address.sin_family = AF_INET;
- server_address.sin_addr = in_addr(ip);
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wold-style-cast"
-#if __GNUC__ > 4 || __GNUC_MINOR__ >= 8
-# pragma GCC diagnostic ignored "-Wuseless-cast"
-#endif
- server_address.sin_port = htons(port);
-#pragma GCC diagnostic pop
-
- fd.fcntl(F_SETFL, O_NONBLOCK);
-
- /// Errors not caught - we must not block
- /// Let the main select() loop detect when we know the state
- fd.connect(reinterpret_cast<struct sockaddr *>(&server_address),
- sizeof(struct sockaddr_in));
-
- readfds.set(fd);
-
- set_session(fd, make_unique<Session>());
- Session *s = get_session(fd);
- s->fd = fd;
- s->rdata.new_(RFIFO_SIZE);
- s->wdata.new_(WFIFO_SIZE);
-
- s->max_rdata = RFIFO_SIZE;
- s->max_wdata = WFIFO_SIZE;
- s->func_recv = recv_to_fifo;
- s->func_send = send_from_fifo;
- s->func_parse = default_func_parse;
- s->created = TimeT::now();
- s->connected = 1;
-
- return s;
-}
-
-void delete_session(Session *s)
-{
- if (!s)
- return;
-
- io::FD fd = s->fd;
- // If this was the highest fd, decrease it
- // We could add a loop to decrement fd_max further for every null session,
- // but this is cheap and good enough for the typical case
- if (fd.uncast_dammit() == fd_max - 1)
- fd_max--;
- readfds.clr(fd);
- {
- s->rdata.delete_();
- s->wdata.delete_();
- s->session_data.reset();
- reset_session(fd);
- }
-
- // just close() would try to keep sending buffers
- fd.shutdown(SHUT_RDWR);
- fd.close();
-}
-
-void realloc_fifo(Session *s, size_t rfifo_size, size_t wfifo_size)
-{
- if (s->max_rdata != rfifo_size && s->rdata_size < rfifo_size)
- {
- s->rdata.resize(rfifo_size);
- s->max_rdata = rfifo_size;
- }
- if (s->max_wdata != wfifo_size && s->wdata_size < wfifo_size)
- {
- s->wdata.resize(wfifo_size);
- s->max_wdata = wfifo_size;
- }
-}
-
-void WFIFOSET(Session *s, size_t len)
-{
- if (s->wdata_size + len + 16384 > s->max_wdata)
- {
- realloc_fifo(s, s->max_rdata, s->max_wdata << 1);
- PRINTF("socket: %d wdata expanded to %zu bytes.\n", s, s->max_wdata);
- }
- if (s->wdata_size + len + 2048 < s->max_wdata)
- s->wdata_size += len;
- else
- FPRINTF(stderr, "socket: %d wdata lost !!\n", s), abort();
-}
-
-void do_sendrecv(interval_t next_ms)
-{
- bool any = false;
- io::FD_Set rfd = readfds, wfd;
- for (io::FD i : iter_fds())
- {
- Session *s = get_session(i);
- if (s)
- {
- any = true;
- if (s->wdata_size)
- wfd.set(i);
- }
- }
- if (!any)
- {
- if (!has_timers())
- {
- PRINTF("Shutting down - nothing to do\n");
- runflag = false;
- }
- return;
- }
- struct timeval timeout;
- {
- std::chrono::seconds next_s = std::chrono::duration_cast<std::chrono::seconds>(next_ms);
- std::chrono::microseconds next_us = next_ms - next_s;
- timeout.tv_sec = next_s.count();
- timeout.tv_usec = next_us.count();
- }
- if (io::FD_Set::select(fd_max, &rfd, &wfd, NULL, &timeout) <= 0)
- return;
- for (io::FD i : iter_fds())
- {
- Session *s = get_session(i);
- if (!s)
- continue;
- if (wfd.isset(i))
- {
- if (s->func_send)
- //send_from_fifo(i);
- s->func_send(s);
- }
- if (rfd.isset(i))
- {
- if (s->func_recv)
- //recv_to_fifo(i);
- //or connect_client(i);
- s->func_recv(s);
- }
- }
-}
-
-void do_parsepacket(void)
-{
- for (io::FD i : iter_fds())
- {
- Session *s = get_session(i);
- if (!s)
- continue;
- if (!s->connected
- && static_cast<time_t>(TimeT::now()) - static_cast<time_t>(s->created) > CONNECT_TIMEOUT)
- {
- PRINTF("Session #%d timed out\n", s);
- s->eof = 1;
- }
- if (!s->rdata_size && !s->eof)
- continue;
- if (s->func_parse)
- {
- s->func_parse(s);
- /// some func_parse may call delete_session
- s = get_session(i);
- if (s && s->eof)
- {
- delete_session(s);
- s = nullptr;
- }
- if (!s)
- continue;
- }
- /// Reclaim buffer space for what was read
- RFIFOFLUSH(s);
- }
-}
-
-void RFIFOSKIP(Session *s, size_t len)
-{
- s->rdata_pos += len;
-
- if (s->rdata_size < s->rdata_pos)
- {
- FPRINTF(stderr, "too many skip\n");
- abort();
- }
-}
diff --git a/src/common/socket.hpp b/src/common/socket.hpp
deleted file mode 100644
index e0847ac..0000000
--- a/src/common/socket.hpp
+++ /dev/null
@@ -1,371 +0,0 @@
-#ifndef SOCKET_HPP
-#define SOCKET_HPP
-
-# include "../sanity.hpp"
-
-# include <netinet/in.h>
-
-# include <cstdio>
-
-# include <array>
-
-# include "../strings/astring.hpp"
-# include "../strings/vstring.hpp"
-# include "../strings/xstring.hpp"
-
-# include "../io/fd.hpp"
-
-# include "dumb_ptr.hpp"
-# include "ip.hpp"
-# include "utils.hpp"
-# include "timer.t.hpp"
-
-struct SessionData
-{
-};
-struct SessionDeleter
-{
- // defined per-server
- void operator()(SessionData *sd);
-};
-
-// Struct declaration
-
-struct Session
-{
- /// Checks whether a newly-connected socket actually does anything
- TimeT created;
- bool connected;
-
- /// Flag needed since structure must be freed in a server-dependent manner
- bool eof;
-
- /// Since this is a single-threaded application, it can't block
- /// These are the read/write queues
- dumb_ptr<uint8_t[]> rdata, wdata;
- size_t max_rdata, max_wdata;
- /// How much is actually in the queue
- size_t rdata_size, wdata_size;
- /// How much has already been read from the queue
- /// Note that there is no need for a wdata_pos
- size_t rdata_pos;
-
- IP4Address client_ip;
-
- /// Send or recieve
- /// Only called when select() indicates the socket is ready
- /// If, after that, nothing is read, it sets eof
- // These could probably be hard-coded with a little work
- void (*func_recv)(Session *);
- void (*func_send)(Session *);
- /// This is the important one
- /// Set to different functions depending on whether the connection
- /// is a player or a server/ladmin
- /// Can be set explicitly or via set_defaultparse
- void (*func_parse)(Session *);
- /// Server-specific data type
- std::unique_ptr<SessionData, SessionDeleter> session_data;
-
- io::FD fd;
-};
-
-inline
-int convert_for_printf(Session *s)
-{
- return s->fd.uncast_dammit();
-}
-
-// save file descriptors for important stuff
-constexpr int SOFT_LIMIT = FD_SETSIZE - 50;
-
-// socket timeout to establish a full connection in seconds
-constexpr int CONNECT_TIMEOUT = 15;
-
-
-void set_session(io::FD fd, std::unique_ptr<Session> sess);
-Session *get_session(io::FD fd);
-void reset_session(io::FD fd);
-int get_fd_max();
-
-class IncrFD
-{
-public:
- static
- io::FD inced(io::FD v)
- {
- return io::FD::cast_dammit(v.uncast_dammit() + 1);
- }
-};
-IteratorPair<ValueIterator<io::FD, IncrFD>> iter_fds();
-
-
-/// open a socket, bind, and listen. Return an fd, or -1 if socket() fails,
-/// but exit if bind() or listen() fails
-Session *make_listen_port(uint16_t port);
-/// Connect to an address, return a connected socket or -1
-// FIXME - this is IPv4 only!
-Session *make_connection(IP4Address ip, uint16_t port);
-/// free() the structure and close() the fd
-void delete_session(Session *);
-/// Make a the internal queues bigger
-void realloc_fifo(Session *s, size_t rfifo_size, size_t wfifo_size);
-/// Update all sockets that can be read/written from the queues
-void do_sendrecv(interval_t next);
-/// Call the parser function for every socket that has read data
-void do_parsepacket(void);
-
-/// Change the default parser for newly connected clients
-// typically called once per server, but individual clients may identify
-// themselves as servers
-void set_defaultparse(void(*defaultparse)(Session *));
-
-template<class T>
-uint8_t *pod_addressof_m(T& structure)
-{
- static_assert(is_trivially_copyable<T>::value, "Can only byte-copy POD-ish structs");
- return &reinterpret_cast<uint8_t&>(structure);
-}
-
-template<class T>
-const uint8_t *pod_addressof_c(const T& structure)
-{
- static_assert(is_trivially_copyable<T>::value, "Can only byte-copy POD-ish structs");
- return &reinterpret_cast<const uint8_t&>(structure);
-}
-
-
-/// Check how much can be read
-inline
-size_t RFIFOREST(Session *s)
-{
- return s->rdata_size - s->rdata_pos;
-}
-/// Read from the queue
-inline
-const void *RFIFOP(Session *s, size_t pos)
-{
- return &s->rdata[s->rdata_pos + pos];
-}
-inline
-uint8_t RFIFOB(Session *s, size_t pos)
-{
- return *static_cast<const uint8_t *>(RFIFOP(s, pos));
-}
-inline
-uint16_t RFIFOW(Session *s, size_t pos)
-{
- return *static_cast<const uint16_t *>(RFIFOP(s, pos));
-}
-inline
-uint32_t RFIFOL(Session *s, size_t pos)
-{
- return *static_cast<const uint32_t *>(RFIFOP(s, pos));
-}
-template<class T>
-void RFIFO_STRUCT(Session *s, size_t pos, T& structure)
-{
- really_memcpy(pod_addressof_m(structure), static_cast<const uint8_t *>(RFIFOP(s, pos)), sizeof(T));
-}
-inline
-IP4Address RFIFOIP(Session *s, size_t pos)
-{
- IP4Address o;
- RFIFO_STRUCT(s, pos, o);
- return o;
-}
-template<uint8_t len>
-inline
-VString<len-1> RFIFO_STRING(Session *s, size_t pos)
-{
- const char *const begin = static_cast<const char *>(RFIFOP(s, pos));
- const char *const end = begin + len-1;
- const char *const mid = std::find(begin, end, '\0');
- return XString(begin, mid, nullptr);
-}
-inline
-AString RFIFO_STRING(Session *s, size_t pos, size_t len)
-{
- const char *const begin = static_cast<const char *>(RFIFOP(s, pos));
- const char *const end = begin + len;
- const char *const mid = std::find(begin, end, '\0');
- return XString(begin, mid, nullptr);
-}
-inline
-void RFIFO_BUF_CLONE(Session *s, uint8_t *buf, size_t len)
-{
- really_memcpy(buf, static_cast<const uint8_t *>(RFIFOP(s, 0)), len);
-}
-
-/// Done reading
-void RFIFOSKIP(Session *s, size_t len);
-
-/// Read from an arbitrary buffer
-inline
-const void *RBUFP(const uint8_t *p, size_t pos)
-{
- return p + pos;
-}
-inline
-uint8_t RBUFB(const uint8_t *p, size_t pos)
-{
- return *static_cast<const uint8_t *>(RBUFP(p, pos));
-}
-inline
-uint16_t RBUFW(const uint8_t *p, size_t pos)
-{
- return *static_cast<const uint16_t *>(RBUFP(p, pos));
-}
-inline
-uint32_t RBUFL(const uint8_t *p, size_t pos)
-{
- return *static_cast<const uint32_t *>(RBUFP(p, pos));
-}
-template<class T>
-void RBUF_STRUCT(const uint8_t *p, size_t pos, T& structure)
-{
- really_memcpy(pod_addressof_m(structure), p + pos, sizeof(T));
-}
-inline
-IP4Address RBUFIP(const uint8_t *p, size_t pos)
-{
- IP4Address o;
- RBUF_STRUCT(p, pos, o);
- return o;
-}
-template<uint8_t len>
-inline
-VString<len-1> RBUF_STRING(const uint8_t *p, size_t pos)
-{
- const char *const begin = static_cast<const char *>(RBUFP(p, pos));
- const char *const end = begin + len-1;
- const char *const mid = std::find(begin, end, '\0');
- return XString(begin, mid, nullptr);
-}
-inline
-AString RBUF_STRING(const uint8_t *p, size_t pos, size_t len)
-{
- const char *const begin = static_cast<const char *>(RBUFP(p, pos));
- const char *const end = begin + len;
- const char *const mid = std::find(begin, end, '\0');
- return XString(begin, mid, nullptr);
-}
-
-
-/// Unused - check how much data can be written
-// the existence of this seems scary
-inline
-size_t WFIFOSPACE(Session *s)
-{
- return s->max_wdata - s->wdata_size;
-}
-/// Write to the queue
-inline
-void *WFIFOP(Session *s, size_t pos)
-{
- return &s->wdata[s->wdata_size + pos];
-}
-inline
-uint8_t& WFIFOB(Session *s, size_t pos)
-{
- return *static_cast<uint8_t *>(WFIFOP(s, pos));
-}
-inline
-uint16_t& WFIFOW(Session *s, size_t pos)
-{
- return *static_cast<uint16_t *>(WFIFOP(s, pos));
-}
-inline
-uint32_t& WFIFOL(Session *s, size_t pos)
-{
- return *static_cast<uint32_t *>(WFIFOP(s, pos));
-}
-template<class T>
-void WFIFO_STRUCT(Session *s, size_t pos, T& structure)
-{
- really_memcpy(static_cast<uint8_t *>(WFIFOP(s, pos)), pod_addressof_c(structure), sizeof(T));
-}
-inline
-IP4Address& WFIFOIP(Session *s, size_t pos)
-{
- static_assert(is_trivially_copyable<IP4Address>::value, "That was the whole point");
- return *static_cast<IP4Address *>(WFIFOP(s, pos));
-}
-inline
-void WFIFO_STRING(Session *s, size_t pos, XString str, size_t len)
-{
- char *const begin = static_cast<char *>(WFIFOP(s, pos));
- char *const end = begin + len;
- char *const mid = std::copy(str.begin(), str.end(), begin);
- std::fill(mid, end, '\0');
-}
-inline
-void WFIFO_ZERO(Session *s, size_t pos, size_t len)
-{
- uint8_t *b = static_cast<uint8_t *>(WFIFOP(s, pos));
- uint8_t *e = b + len;
- std::fill(b, e, '\0');
-}
-inline
-void WFIFO_BUF_CLONE(Session *s, const uint8_t *buf, size_t len)
-{
- really_memcpy(static_cast<uint8_t *>(WFIFOP(s, 0)), buf, len);
-}
-
-/// Finish writing
-void WFIFOSET(Session *s, size_t len);
-
-/// Write to an arbitrary buffer
-inline
-void *WBUFP(uint8_t *p, size_t pos)
-{
- return p + pos;
-}
-inline
-uint8_t& WBUFB(uint8_t *p, size_t pos)
-{
- return *static_cast<uint8_t *>(WBUFP(p, pos));
-}
-inline
-uint16_t& WBUFW(uint8_t *p, size_t pos)
-{
- return *static_cast<uint16_t *>(WBUFP(p, pos));
-}
-inline
-uint32_t& WBUFL(uint8_t *p, size_t pos)
-{
- return *static_cast<uint32_t *>(WBUFP(p, pos));
-}
-template<class T>
-void WBUF_STRUCT(uint8_t *p, size_t pos, T& structure)
-{
- really_memcpy(p + pos, pod_addressof_c(structure), sizeof(T));
-}
-inline
-IP4Address& WBUFIP(uint8_t *p, size_t pos)
-{
- return *static_cast<IP4Address *>(WBUFP(p, pos));
-}
-inline
-void WBUF_STRING(uint8_t *p, size_t pos, XString s, size_t len)
-{
- char *const begin = static_cast<char *>(WBUFP(p, pos));
- char *const end = begin + len;
- char *const mid = std::copy(s.begin(), s.end(), begin);
- std::fill(mid, end, '\0');
-}
-inline
-void WBUF_ZERO(uint8_t *p, size_t pos, size_t len)
-{
- uint8_t *b = static_cast<uint8_t *>(WBUFP(p, pos));
- uint8_t *e = b + len;
- std::fill(b, e, '\0');
-}
-
-inline
-void RFIFO_WFIFO_CLONE(Session *rs, Session *ws, size_t len)
-{
- really_memcpy(static_cast<uint8_t *>(WFIFOP(ws, 0)),
- static_cast<const uint8_t *>(RFIFOP(rs, 0)), len);
-}
-
-#endif // SOCKET_HPP
diff --git a/src/common/timer.cpp b/src/common/timer.cpp
deleted file mode 100644
index b5a2a5e..0000000
--- a/src/common/timer.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-#include "timer.hpp"
-
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#include <cassert>
-#include <cstring>
-
-#include <queue>
-
-#include "../strings/zstring.hpp"
-
-#include "../io/cxxstdio.hpp"
-
-#include "utils.hpp"
-
-#include "../poison.hpp"
-
-struct TimerData
-{
- /// This will be reset on call, to avoid problems.
- Timer *owner;
-
- /// When it will be triggered
- tick_t tick;
- /// What will be done
- timer_func func;
- /// Repeat rate - 0 for oneshot
- interval_t interval;
-
- TimerData(Timer *o, tick_t t, timer_func f, interval_t i)
- : owner(o)
- , tick(t)
- , func(std::move(f))
- , interval(i)
- {}
-};
-
-struct TimerCompare
-{
- /// implement "less than"
- bool operator() (dumb_ptr<TimerData> l, dumb_ptr<TimerData> r)
- {
- // C++ provides a max-heap, but we want
- // the smallest tick to be the head (a min-heap).
- return l->tick > r->tick;
- }
-};
-
-static
-std::priority_queue<dumb_ptr<TimerData>, std::vector<dumb_ptr<TimerData>>, TimerCompare> timer_heap;
-
-
-tick_t gettick_cache;
-
-tick_t milli_clock::now(void) noexcept
-{
- struct timeval tval;
- // BUG: This will cause strange behavior if the system clock is changed!
- // it should be reimplemented in terms of clock_gettime(CLOCK_MONOTONIC, )
- gettimeofday(&tval, NULL);
- return gettick_cache = tick_t(std::chrono::seconds(tval.tv_sec)
- + std::chrono::duration_cast<std::chrono::milliseconds>(
- std::chrono::microseconds(tval.tv_usec)));
-}
-
-static
-void do_nothing(TimerData *, tick_t)
-{
-}
-
-void Timer::cancel()
-{
- if (!td)
- return;
-
- assert (this == td->owner);
- td->owner = nullptr;
- td->func = do_nothing;
- td->interval = interval_t::zero();
- td = nullptr;
-}
-
-void Timer::detach()
-{
- assert (this == td->owner);
- td->owner = nullptr;
- td = nullptr;
-}
-
-static
-void push_timer_heap(dumb_ptr<TimerData> td)
-{
- timer_heap.push(td);
-}
-
-static
-dumb_ptr<TimerData> top_timer_heap(void)
-{
- if (timer_heap.empty())
- return dumb_ptr<TimerData>();
- return timer_heap.top();
-}
-
-static
-void pop_timer_heap(void)
-{
- timer_heap.pop();
-}
-
-Timer::Timer(tick_t tick, timer_func func, interval_t interval)
-: td(dumb_ptr<TimerData>::make(this, tick, std::move(func), interval))
-{
- assert (interval >= interval_t::zero());
-
- push_timer_heap(td);
-}
-
-Timer::Timer(Timer&& t)
-: td(t.td)
-{
- t.td = nullptr;
- if (td)
- {
- assert (td->owner == &t);
- td->owner = this;
- }
-}
-
-Timer& Timer::operator = (Timer&& t)
-{
- std::swap(td, t.td);
- if (td)
- {
- assert (td->owner == &t);
- td->owner = this;
- }
- if (t.td)
- {
- assert (t.td->owner == this);
- t.td->owner = &t;
- }
- return *this;
-}
-
-interval_t do_timer(tick_t tick)
-{
- /// Number of milliseconds until it calls this again
- // this says to wait 1 sec if all timers get popped
- interval_t nextmin = std::chrono::seconds(1);
-
- while (dumb_ptr<TimerData> td = top_timer_heap())
- {
- // while the heap is not empty and
- if (td->tick > tick)
- {
- /// Return the time until the next timer needs to goes off
- nextmin = td->tick - tick;
- break;
- }
- pop_timer_heap();
-
- // Prevent destroying the object we're in.
- // Note: this would be surprising in an interval timer,
- // but all interval timers do an immediate explicit detach().
- if (td->owner)
- td->owner->detach();
- // If we are too far past the requested tick, call with
- // the current tick instead to fix reregistration problems
- if (td->tick + std::chrono::seconds(1) < tick)
- td->func(td.operator->(), tick);
- else
- td->func(td.operator->(), td->tick);
-
- if (td->interval == interval_t::zero())
- {
- td.delete_();
- continue;
- }
- if (td->tick + std::chrono::seconds(1) < tick)
- td->tick = tick + td->interval;
- else
- td->tick += td->interval;
- push_timer_heap(td);
- }
-
- return std::max(nextmin, std::chrono::milliseconds(10));
-}
-
-tick_t file_modified(ZString name)
-{
- struct stat buf;
- if (stat(name.c_str(), &buf))
- return tick_t();
- return tick_t(std::chrono::seconds(buf.st_mtime));
-}
-
-bool has_timers()
-{
- return !timer_heap.empty();
-}
diff --git a/src/common/timer.hpp b/src/common/timer.hpp
deleted file mode 100644
index 7e187a3..0000000
--- a/src/common/timer.hpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef TIMER_HPP
-#define TIMER_HPP
-
-# include "timer.t.hpp"
-
-# include "../sanity.hpp"
-
-# include "../strings/fwd.hpp"
-
-// updated automatically when using milli_clock::now()
-// which is done only by core.cpp
-extern tick_t gettick_cache;
-
-inline
-tick_t gettick(void)
-{
- return gettick_cache;
-}
-
-/// Do all timers scheduled before tick, and return the number of
-/// milliseconds until the next timer happens
-interval_t do_timer(tick_t tick);
-
-/// Stat a file, and return its modification time, truncated to seconds.
-tick_t file_modified(ZString name);
-
-/// Check if there are any events at all scheduled.
-bool has_timers();
-
-#endif // TIMER_HPP
diff --git a/src/common/timer.t.hpp b/src/common/timer.t.hpp
deleted file mode 100644
index 1e3a87a..0000000
--- a/src/common/timer.t.hpp
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef TIMER_T_HPP
-#define TIMER_T_HPP
-
-# include <chrono>
-# include <functional>
-
-# include "dumb_ptr.hpp"
-
-struct TimerData;
-
-/// An implementation of the C++ "clock" concept, exposing
-/// durations in milliseconds.
-class milli_clock
-{
-public:
- typedef std::chrono::milliseconds duration;
- typedef duration::rep rep;
- typedef duration::period period;
- typedef std::chrono::time_point<milli_clock, duration> time_point;
- static const bool is_steady = true; // assumed - not necessarily true
-
- static time_point now() noexcept;
-};
-
-/// A point in time.
-typedef milli_clock::time_point tick_t;
-/// The difference between two points in time.
-typedef milli_clock::duration interval_t;
-/// (to get additional arguments, use std::bind or a lambda).
-typedef std::function<void (TimerData *, tick_t)> timer_func;
-
-class Timer
-{
- friend struct TimerData;
- dumb_ptr<TimerData> td;
-
- Timer(const Timer&) = delete;
- Timer& operator = (const Timer&) = delete;
-public:
- /// Don't own anything yet.
- Timer() = default;
- /// Schedule a timer for the given tick.
- /// If you do not wish to keep track of it, call disconnect().
- /// Otherwise, you may cancel() or replace (operator =) it later.
- ///
- /// If the interval argument is given, the timer will reschedule
- /// itself again forever. Otherwise, it will disconnect() itself
- /// just BEFORE it is called.
- Timer(tick_t tick, timer_func func, interval_t interval=interval_t::zero());
-
- Timer(Timer&& t);
- Timer& operator = (Timer&& t);
- ~Timer() { cancel(); }
-
- /// Cancel the delivery of this timer's function, and make it falsy.
- /// Implementation note: this doesn't actually remove it, just sets
- /// the functor to do_nothing, and waits for the tick before removing.
- void cancel();
- /// Make it falsy without cancelling the timer,
- void detach();
-
- /// Check if there is a timer connected.
- explicit operator bool() { return bool(td); }
- /// Check if there is no connected timer.
- bool operator !() { return !td; }
-};
-
-#endif // TIMER_T_HPP
diff --git a/src/common/utils.cpp b/src/common/utils.cpp
deleted file mode 100644
index 0dbf145..0000000
--- a/src/common/utils.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-#include "utils.hpp"
-
-#include <netinet/in.h>
-#include <sys/time.h>
-
-#include <algorithm>
-
-#include "../strings/astring.hpp"
-#include "../strings/zstring.hpp"
-#include "../strings/xstring.hpp"
-
-#include "../io/cxxstdio.hpp"
-#include "../io/write.hpp"
-
-#include "extract.hpp"
-
-#include "../poison.hpp"
-
-//---------------------------------------------------
-// E-mail check: return 0 (not correct) or 1 (valid).
-//---------------------------------------------------
-bool e_mail_check(XString email)
-{
- // athena limits
- if (email.size() < 3 || email.size() > 39)
- return 0;
-
- // part of RFC limits (official reference of e-mail description)
- XString::iterator at = std::find(email.begin(), email.end(), '@');
- if (at == email.end())
- return 0;
- XString username = email.xislice_h(at);
- XString hostname = email.xislice_t(at + 1);
- if (!username || !hostname)
- return 0;
- if (hostname.contains('@'))
- return 0;
- if (hostname.front() == '.' || hostname.back() == '.')
- return 0;
- if (hostname.contains_seq(".."))
- return 0;
- if (email.contains_any(" ;"))
- return 0;
- return email.is_print();
-}
-
-//-------------------------------------------------
-// Return numerical value of a switch configuration
-// on/off, english, français, deutsch, español
-//-------------------------------------------------
-int config_switch(ZString str)
-{
- if (str == "true" || str == "on" || str == "yes"
- || str == "oui" || str == "ja"
- || str == "si")
- return 1;
- if (str == "false" || str == "off" || str == "no"
- || str == "non" || str == "nein")
- return 0;
-
- int rv;
- if (extract(str, &rv))
- return rv;
- FPRINTF(stderr, "Fatal: bad option value %s", str);
- abort();
-}
-
-static_assert(sizeof(timestamp_seconds_buffer) == 20, "seconds buffer");
-static_assert(sizeof(timestamp_milliseconds_buffer) == 24, "millis buffer");
-
-void stamp_time(timestamp_seconds_buffer& out, const TimeT *t)
-{
- struct tm when = t ? *t : TimeT::now();
- char buf[20];
- strftime(buf, 20, "%Y-%m-%d %H:%M:%S", &when);
- out = stringish<timestamp_seconds_buffer>(const_(buf));
-}
-void stamp_time(timestamp_milliseconds_buffer& out)
-{
- struct timeval tv;
- gettimeofday(&tv, NULL);
- struct tm when = TimeT(tv.tv_sec);
- char buf[24];
- strftime(buf, 20, "%Y-%m-%d %H:%M:%S", &when);
- sprintf(buf + 19, ".%03d", static_cast<int>(tv.tv_usec / 1000));
- out = stringish<timestamp_milliseconds_buffer>(const_(buf));
-}
-
-void log_with_timestamp(io::WriteFile& out, XString line)
-{
- if (!line)
- {
- out.put('\n');
- return;
- }
- timestamp_milliseconds_buffer tmpstr;
- stamp_time(tmpstr);
- out.really_put(tmpstr.data(), tmpstr.size());
- out.really_put(": ", 2);
- out.put_line(line);
-}
diff --git a/src/common/utils.hpp b/src/common/utils.hpp
deleted file mode 100644
index 161cbd4..0000000
--- a/src/common/utils.hpp
+++ /dev/null
@@ -1,140 +0,0 @@
-#ifndef UTILS_HPP
-#define UTILS_HPP
-
-# include "../sanity.hpp"
-
-# include <cstdio>
-# include <cstring>
-
-# include <type_traits>
-
-# include "../strings/fwd.hpp"
-# include "../strings/vstring.hpp"
-
-# include "../io/fwd.hpp"
-
-# include "const_array.hpp"
-# include "operators.hpp"
-# include "utils2.hpp"
-
-template<class T>
-struct is_trivially_copyable
-: std::integral_constant<bool,
- // come back when GCC actually implements the public traits properly
- __has_trivial_copy(T)
- && __has_trivial_assign(T)
- && __has_trivial_destructor(T)>
-{};
-
-bool e_mail_check(XString email);
-int config_switch (ZString str);
-
-inline
-void really_memcpy(uint8_t *dest, const uint8_t *src, size_t n)
-{
- memcpy(dest, src, n);
-}
-
-inline
-void really_memmove(uint8_t *dest, const uint8_t *src, size_t n)
-{
- memmove(dest, src, n);
-}
-inline
-bool really_memequal(const uint8_t *a, const uint8_t *b, size_t n)
-{
- return memcmp(a, b, n) == 0;
-}
-
-inline
-void really_memset0(uint8_t *dest, size_t n)
-{
- memset(dest, '\0', n);
-}
-template<class T>
-void really_memzero_this(T *v)
-{
- static_assert(is_trivially_copyable<T>::value, "only for mostly-pod types");
- static_assert(std::is_class<T>::value || std::is_union<T>::value, "Only for user-defined structures (for now)");
- memset(v, '\0', sizeof(*v));
-}
-template<class T, size_t n>
-void really_memzero_this(T (&)[n]) = delete;
-
-// Exists in place of time_t, to give it a predictable printf-format.
-// (on x86 and amd64, time_t == long, but not on x32)
-static_assert(sizeof(long long) >= sizeof(time_t), "long long >= time_t");
-struct TimeT : Comparable
-{
- long long value;
-
- // conversion
- TimeT(time_t t=0) : value(t) {}
- TimeT(struct tm t) : value(timegm(&t)) {}
- operator time_t() const { return value; }
- operator struct tm() const { time_t v = value; return *gmtime(&v); }
-
- explicit operator bool() const { return value; }
- bool operator !() const { return !value; }
-
- // prevent surprises
- template<class T>
- TimeT(T) = delete;
- template<class T>
- operator T() const = delete;
-
- static
- TimeT now()
- {
- // poisoned, but this is still in header-land
- return time(NULL);
- }
-
- bool error() const
- {
- return value == -1;
- }
- bool okay() const
- {
- return !error();
- }
-};
-
-inline
-long long convert_for_printf(TimeT t)
-{
- return t.value;
-}
-
-inline
-long long& convert_for_scanf(TimeT& t)
-{
- return t.value;
-}
-
-struct timestamp_seconds_buffer : VString<19> {};
-struct timestamp_milliseconds_buffer : VString<23> {};
-void stamp_time(timestamp_seconds_buffer&, const TimeT *t=nullptr);
-void stamp_time(timestamp_milliseconds_buffer&);
-
-void log_with_timestamp(io::WriteFile& out, XString line);
-
-// TODO VString?
-# define TIMESTAMP_DUMMY "YYYY-MM-DD HH:MM:SS"
-static_assert(sizeof(TIMESTAMP_DUMMY) == sizeof(timestamp_seconds_buffer),
- "timestamp size");
-# define WITH_TIMESTAMP(str) str TIMESTAMP_DUMMY
-// str: prefix: YYYY-MM-DD HH:MM:SS
-// sizeof: 01234567890123456789012345678
-// str + sizeof: ^
-// -1: ^
-// there's probably a better way to do this now
-# define REPLACE_TIMESTAMP(str, t) \
- stamp_time( \
- reinterpret_cast<timestamp_seconds_buffer *>( \
- str + sizeof(str) \
- )[-1], \
- &t \
- )
-
-#endif //UTILS_HPP
diff --git a/src/common/utils2.hpp b/src/common/utils2.hpp
deleted file mode 100644
index 9af39e5..0000000
--- a/src/common/utils2.hpp
+++ /dev/null
@@ -1,256 +0,0 @@
-#ifndef UTILS2_HPP
-#define UTILS2_HPP
-
-# include "../sanity.hpp"
-
-# include <algorithm>
-# include <functional>
-# include <iterator>
-# include <memory>
-# include <type_traits>
-
-# include "iter.hpp"
-
-# ifdef __clang__
-# define FALLTHROUGH [[clang::fallthrough]]
-# else
-# define FALLTHROUGH /* fallthrough */
-# endif
-
-template<class T, class E, E max>
-struct earray
-{
- // no ctor/dtor and one public member variable for easy initialization
- T _data[size_t(max)];
-
- T& operator[](E v)
- {
- return _data[size_t(v)];
- }
-
- const T& operator[](E v) const
- {
- return _data[size_t(v)];
- }
-
- T *begin()
- {
- return _data;
- }
-
- T *end()
- {
- return _data + size_t(max);
- }
-
- const T *begin() const
- {
- return _data;
- }
-
- const T *end() const
- {
- return _data + size_t(max);
- }
-
- friend bool operator == (const earray& l, const earray& r)
- {
- return std::equal(l.begin(), l.end(), r.begin());
- }
-
- friend bool operator != (const earray& l, const earray& r)
- {
- return !(l == r);
- }
-};
-
-template<class T, class E>
-class eptr
-{
- T *_data;
-public:
- eptr(decltype(nullptr)=nullptr)
- : _data(nullptr)
- {}
-
- template<E max>
- eptr(earray<T, E, max>& arr)
- : _data(arr._data)
- {}
-
- T& operator [](E v)
- {
- return _data[size_t(v)];
- }
-
- explicit operator bool()
- {
- return _data;
- }
-
- bool operator not()
- {
- return not _data;
- }
-};
-
-// std::underlying_type isn't supported until gcc 4.7
-// this is a poor man's emulation
-template<class E>
-struct underlying_type
-{
- static_assert(std::is_enum<E>::value, "Only enums have underlying type!");
- typedef typename std::conditional<
- std::is_signed<E>::value,
- typename std::make_signed<E>::type,
- typename std::make_unsigned<E>::type
- >::type type;
-};
-
-template<class E, bool=std::is_enum<E>::value>
-struct remove_enum
-{
- typedef E type;
-};
-template<class E>
-struct remove_enum<E, true>
-{
- typedef typename underlying_type<E>::type type;
-};
-
-
-# define ENUM_BITWISE_OPERATORS(E) \
-inline \
-E operator & (E l, E r) \
-{ \
- typedef underlying_type<E>::type U; \
- return E(U(l) & U(r)); \
-} \
-inline \
-E operator | (E l, E r) \
-{ \
- typedef underlying_type<E>::type U; \
- return E(U(l) | U(r)); \
-} \
-inline \
-E operator ^ (E l, E r) \
-{ \
- typedef underlying_type<E>::type U; \
- return E(U(l) ^ U(r)); \
-} \
-inline \
-E& operator &= (E& l, E r) \
-{ \
- return l = l & r; \
-} \
-inline \
-E& operator |= (E& l, E r) \
-{ \
- return l = l | r; \
-} \
-inline \
-E& operator ^= (E& l, E r) \
-{ \
- return l = l ^ r; \
-} \
-inline \
-E operator ~ (E r) \
-{ \
- return E(-1) ^ r; \
-}
-
-template<class E>
-class EnumMath
-{
- typedef typename underlying_type<E>::type U;
-public:
- static
- E inced(E v)
- {
- return E(U(v) + 1);
- }
-};
-
-template<class E>
-IteratorPair<ValueIterator<E, EnumMath<E>>> erange(E b, E e)
-{
- return {b, e};
-}
-
-namespace ph = std::placeholders;
-
-template<class A, class B>
-typename std::common_type<A, B>::type min(A a, B b)
-{
- return a < b ? a : b;
-}
-
-template<class A, class B>
-typename std::common_type<A, B>::type max(A a, B b)
-{
- return b < a ? a : b;
-}
-
-template<class T>
-struct is_array_of_unknown_bound
-: std::is_same<T, typename std::remove_extent<T>::type[]>
-{};
-
-template<class T, class D=std::default_delete<T>, class... A>
-typename std::enable_if<!is_array_of_unknown_bound<T>::value, std::unique_ptr<T, D>>::type make_unique(A&&... a)
-{
- return std::unique_ptr<T, D>(new T(std::forward<A>(a)...));
-}
-
-template<class T, class D=std::default_delete<T>>
-typename std::enable_if<is_array_of_unknown_bound<T>::value, std::unique_ptr<T, D>>::type make_unique(size_t sz)
-{
- typedef typename std::remove_extent<T>::type E;
- return std::unique_ptr<E[], D>(new E[sz]());
-}
-
-template<class T>
-const T& const_(T& t)
-{
- return t;
-}
-
-template<class T, class U>
-T no_cast(U&& u)
-{
- typedef typename std::remove_reference<T>::type Ti;
- typedef typename std::remove_reference<U>::type Ui;
- typedef typename std::remove_cv<Ti>::type Tb;
- typedef typename std::remove_cv<Ui>::type Ub;
- static_assert(std::is_same<Tb, Ub>::value, "not no cast");
- return std::forward<U>(u);
-}
-
-template<class T, class U>
-T base_cast(U&& u)
-{
- static_assert(std::is_reference<T>::value, "must base cast with references");
- typedef typename std::remove_reference<T>::type Ti;
- typedef typename std::remove_reference<U>::type Ui;
- typedef typename std::remove_cv<Ti>::type Tb;
- typedef typename std::remove_cv<Ui>::type Ub;
- static_assert(std::is_base_of<Tb, Ub>::value, "not base cast");
- return std::forward<U>(u);
-}
-
-// use this when e.g. U is an int of unknown size
-template<class T, class U>
-T maybe_cast(U u)
-{
- return u;
-}
-
-template<class T, class U>
-typename std::remove_pointer<T>::type *sign_cast(U *u)
-{
- typedef typename std::remove_pointer<T>::type T_;
- static_assert(sizeof(T_) == sizeof(U), "sign cast must be same size");
- return reinterpret_cast<T_ *>(u);
-}
-
-#endif // UTILS2_HPP
diff --git a/src/common/version.cpp b/src/common/version.cpp
deleted file mode 100644
index 811ffdf..0000000
--- a/src/common/version.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#include "version.hpp"
-
-#include "../conf/version.hpp"
-
-#include "../strings/xstring.hpp"
-
-#include "extract.hpp"
-
-Version CURRENT_VERSION =
-{
- VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH,
- VERSION_DEVEL,
-
- 0, 0,
- VENDOR_VERSION,
-};
-Version CURRENT_LOGIN_SERVER_VERSION =
-{
- VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH,
- VERSION_DEVEL,
-
- 0, TMWA_SERVER_LOGIN,
- VENDOR_VERSION,
-};
-Version CURRENT_CHAR_SERVER_VERSION =
-{
- VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH,
- VERSION_DEVEL,
-
- 0, TMWA_SERVER_CHAR | TMWA_SERVER_INTER,
- VENDOR_VERSION,
-};
-Version CURRENT_MAP_SERVER_VERSION =
-{
- VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH,
- VERSION_DEVEL,
-
- 0, TMWA_SERVER_MAP,
- VENDOR_VERSION,
-};
-
-#define S2(a) #a
-#define S(a) S2(a)
-
-const char CURRENT_VERSION_STRING[] = "TMWA "
- S(VERSION_MAJOR) "." S(VERSION_MINOR) "." S(VERSION_PATCH)
- " dev" S(VERSION_DEVEL) " (" VENDOR " " S(VENDOR_VERSION) ")";
-
-bool extract(XString str, Version *vers)
-{
- *vers = {};
- return extract(str, record<'.'>(&vers->major, &vers->minor, &vers->patch));
-}
diff --git a/src/common/version.hpp b/src/common/version.hpp
deleted file mode 100644
index a2c4e05..0000000
--- a/src/common/version.hpp
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef TMWA_COMMON_VERSION_HPP
-#define TMWA_COMMON_VERSION_HPP
-
-# include <cstdint>
-
-# include "../strings/fwd.hpp"
-
-// 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
-
-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 sent over the network, can't change");
-
-extern Version CURRENT_VERSION;
-
-extern Version CURRENT_LOGIN_SERVER_VERSION;
-extern Version CURRENT_CHAR_SERVER_VERSION;
-extern Version CURRENT_MAP_SERVER_VERSION;
-
-extern const char CURRENT_VERSION_STRING[];
-
-bool extract(XString str, Version *vers);
-
-constexpr
-bool operator < (Version l, Version r)
-{
- return (l.major < r.major
- || (l.major == r.major
- && (l.minor < r.minor
- || (l.minor == r.minor
- && (l.patch < r.patch
- || (l.patch == r.patch
- && (l.devel < r.devel
- || (l.devel == r.devel
- && l.vend < r.vend))))))));
-}
-constexpr
-bool operator > (Version l, Version r)
-{
- return r < l;
-}
-constexpr
-bool operator <= (Version l, Version r)
-{
- return !(r < l);
-}
-constexpr
-bool operator >= (Version l, Version r)
-{
- return !(l < r);
-}
-
-#endif // TMWA_COMMON_VERSION_HPP