• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

[C++/Linux] Compiling old engine (sources) on Debian 10 / Ubuntu 20.04

C++:
game.cpp: W konstruktorze 'Game::Game()':
game.cpp: In constructor 'Game::Game()':
game.cpp:80:24: warning: iteration 2 invokes undefined behavior [-Waggressive-loop-optimizations]
   globalSaveMessage[i] = false;
   ~~~~~~~~~~~~~~~~~~~~~^~~~~~~
game.cpp:79:23: note: within this loop
  for(int64_t i = 0; i < 3; i++)
                     ~~^~~
In file included from game.cpp:18:
game.h: In member function 'void Game::globalSave()':
game.h:613:78: warning: iteration 2 invokes undefined behavior [-Waggressive-loop-optimizations]
 setGlobalSaveMessage(int64_t key, bool value) {globalSaveMessage[key] = value;}
                                                ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~

game.cpp:6180:23: note: within this loop
  for(int64_t i = 0; i < 3; i++)
                     ~~^~~
 
C++:
game.cpp: W konstruktorze 'Game::Game()':
game.cpp: In constructor 'Game::Game()':
game.cpp:80:24: warning: iteration 2 invokes undefined behavior [-Waggressive-loop-optimizations]
   globalSaveMessage[i] = false;
   ~~~~~~~~~~~~~~~~~~~~~^~~~~~~
game.cpp:79:23: note: within this loop
  for(int64_t i = 0; i < 3; i++)
                     ~~^~~
In file included from game.cpp:18:
game.h: In member function 'void Game::globalSave()':
game.h:613:78: warning: iteration 2 invokes undefined behavior [-Waggressive-loop-optimizations]
 setGlobalSaveMessage(int64_t key, bool value) {globalSaveMessage[key] = value;}
                                                ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~

game.cpp:6180:23: note: within this loop
  for(int64_t i = 0; i < 3; i++)
                     ~~^~~
-waggressive in makefile?
 
no, only -Wno-strict-aliasing
compare then to mine
:
C++:
void Game::globalSave()
{
    bool close = g_config.getBool(ConfigManager::SHUTDOWN_AT_GLOBALSAVE);
    if(!close) // check are we're going to close the server
        Dispatcher::getInstance().addTask(createTask(boost::bind(&Game::setGameState, this, GAMESTATE_CLOSED)));

    // call the global event
    g_globalEvents->execute(GLOBALEVENT_GLOBALSAVE);
    if(close)
    {
        //shutdown server
        Dispatcher::getInstance().addTask(createTask(boost::bind(&Game::setGameState, this, GAMESTATE_SHUTDOWN)));
        return;
    }

    //pay houses
    Houses::getInstance()->check();
    //clean map if configured to
    if(g_config.getBool(ConfigManager::CLEAN_MAP_AT_GLOBALSAVE))
        cleanMap();

    //remove premium days globally if configured to
    if(g_config.getBool(ConfigManager::INIT_PREMIUM_UPDATE))
        IOLoginData::getInstance()->updatePremiumDays();

    //reload everything
    reloadInfo(RELOAD_ALL);
    //prepare for next global save after 24 hours
    Scheduler::getInstance().addEvent(createSchedulerTask(((24 * 60 * 60) - (5 * 60)) * 1000, boost::bind(&Game::prepareGlobalSave, this, 5)));
    //open server
    Dispatcher::getInstance().addTask(createTask(boost::bind(&Game::setGameState, this, GAMESTATE_NORMAL)));
}
 
game.h:613:78: warning
It says warning. Did it stop compilation?
This code is bugged, but it should compile.

To fix this bug in game.h replace:
C++:
bool globalSaveMessage[2];
with:
C++:
bool globalSaveMessage[3];

About this bug:
bool globalSaveMessage[2]; means this array has 2 elements, their keys are: 0 and 1
Compiler reports bug, because this loop (line 6180 of game.cpp):
C++:
for(int64_t i = 0; i < 3; i++)
and some other parts of code [only first bug is reported, then it stops compilation/error reporting] reads array keys 0, 1 and 2.

Reading key 2 should crash server. It does not, because of memory allocation of Game class. It just reads some not related value and handled it as 3rd key of globalSaveMessage array.

Writing key 2 of globalSaveMessage in line 6258:
Code:
globalSaveMessage[2] = true;
should crash server in moment of this line execution, but it does not. Again it gets some other variable from Game class and overwrite it's value to true. Now it gets even worse. Some other code - that is 100% fine - will crash in random moment, because it will use value modified by line I've posted above!
 
Debian 11.7.0
TFS 0.4 rev 3884
error:
Code:
outputmessage.cpp: In member function ‘OutputMessage_ptr OutputMessagePool::getOutputMessage(Protocol*, bool)’:
outputmessage.cpp:190:57: error: ‘_1’ was not declared in this scope
  190 |   boost::bind(&OutputMessagePool::releaseMessage, this, _1));
      |                                                         ^~
outputmessage.cpp:190:57: note: suggested alternatives:
In file included from /usr/include/boost/mpl/aux_/include_preprocessed.hpp:37,
                 from /usr/include/boost/mpl/placeholders.hpp:43,
                 from /usr/include/boost/iterator/iterator_categories.hpp:16,
                 from /usr/include/boost/iterator/iterator_adaptor.hpp:14,
                 from /usr/include/boost/token_iterator.hpp:22,
                 from /usr/include/boost/tokenizer.hpp:20,
                 from otpch.h:37,
                 from outputmessage.cpp:17:
/usr/include/boost/mpl/aux_/preprocessed/gcc/placeholders.hpp:29:16: note:   ‘mpl_::_1’
   29 | typedef arg<1> _1;
      |                ^~
In file included from /usr/include/boost/function.hpp:23,
                 from otpch.h:34,
                 from outputmessage.cpp:17:
/usr/include/c++/10/functional:221:34: note:   ‘std::placeholders::_1’
  221 |     extern const _Placeholder<1> _1;
      |                                  ^~
In file included from /usr/include/boost/mpl/aux_/include_preprocessed.hpp:37,
                 from /usr/include/boost/mpl/placeholders.hpp:43,
                 from /usr/include/boost/iterator/iterator_categories.hpp:16,
                 from /usr/include/boost/iterator/iterator_adaptor.hpp:14,
                 from /usr/include/boost/token_iterator.hpp:22,
                 from /usr/include/boost/tokenizer.hpp:20,
                 from otpch.h:37,
                 from outputmessage.cpp:17:
/usr/include/boost/mpl/aux_/preprocessed/gcc/placeholders.hpp:29:16: note:   ‘mpl_::_1’
   29 | typedef arg<1> _1;
      |                ^~
In file included from /usr/include/boost/bind/bind.hpp:2356,
                 from otpch.h:35,
                 from outputmessage.cpp:17:
/usr/include/boost/bind/placeholders.hpp:46:38: note:   ‘boost::placeholders::_1’
   46 | BOOST_STATIC_CONSTEXPR boost::arg<1> _1;
      |                                      ^~
In file included from /usr/include/boost/mpl/aux_/include_preprocessed.hpp:37,
                 from /usr/include/boost/mpl/placeholders.hpp:43,
                 from /usr/include/boost/iterator/iterator_categories.hpp:16,
                 from /usr/include/boost/iterator/iterator_adaptor.hpp:14,
                 from /usr/include/boost/token_iterator.hpp:22,
                 from /usr/include/boost/tokenizer.hpp:20,
                 from otpch.h:37,
                 from outputmessage.cpp:17:
/usr/include/boost/mpl/aux_/preprocessed/gcc/placeholders.hpp:29:16: note:   ‘mpl_::_1’
   29 | typedef arg<1> _1;
      |                ^~
make[1]: *** [Makefile:599: outputmessage.o] Error 1
 
@Womos Try changing _1 to boost::arg<1>() in outputmessage.cpp:190
C++:
boost::bind(&OutputMessagePool::releaseMessage, this, boost::arg<1>())
 
@Womos Try changing _1 to boost::arg<1>() in outputmessage.cpp:190
C++:
boost::bind(&OutputMessagePool::releaseMessage, this, boost::arg<1>())
Thanks but it can be fixed by compiling using "make" instead of "./build.sh"
Otland unfortunately doesn't allow to edit posts
 
There are many threads with compilation errors, but I did not find any with full instruction how to fix all problems.

For people familiar with 'git compare':
1)
All errors fixed one by one: gesior/tfs_0.4_on_debian_10 (https://github.com/gesior/tfs_0.4_on_debian_10/commits/main)
2) Total diff of TFS 0.4 rev 3777 update to compile it on Debian 10: gesior/tfs_0.4_on_debian_10 (https://github.com/gesior/tfs_0.4_on_debian_10/compare/c215d09...9664f12)

TFS 0.4 rev 3777 sources updated to compile on Debian 10: gesior/tfs_0.4_on_debian_10 (https://github.com/gesior/tfs_0.4_on_debian_10)

Packages required to compile old engines on Debian 10:
Code:
apt install libboost-all-dev libgmp3-dev liblua5.1-0 liblua5.1-0-dev  lua5.1 libxml2-dev libxml++2.6-dev zlib1g-dev zlib1g libcrypto++-dev libcrypto++6 libssl-dev libmariadb-dev libmariadb-dev-compat cpp gcc g++ make autoconf

TFS 0.4 commands to compile on Debian 10:
Code:
sh autogen.sh
./configure --enable-mysql --disable-dependency-tracking
sh build.sh

Step by step error fixing instruction:
0)
Get some program to search in all files in 'sources' directory, like Notepad++/Sublime Text, some IDE or in case of linux terminal "grep -R"
1) Error:
Code:
checking boost/tr1/unordered_set.hpp usability... no
checking boost/tr1/unordered_set.hpp presence... no
checking for boost/tr1/unordered_set.hpp... no
configure: error: "boost::unordered_set header not found."
Search in all files in 'sources' directory.
Replace every:
Code:
/tr1/
with:
Code:
/
Replace every:
Code:
std::tr1::
with:
Code:
boost::

2) Error:
Code:
chat.cpp: In member function ‘ChatChannel* Chat::getChannel(Player*, uint16_t)’:
chat.cpp:1144:10: error: cannot convert ‘bool’ to ‘ChatChannel*’ in return
1144 |   return false;
replace at 1144 line - it's in function "ChatChannel* Chat::getChannel(Player*, uint16_t)" - of chat.cpp:
Code:
return false;
with:
Code:
return NULL;

3) Error:
Code:
connection.cpp: In member function ‘void Connection::accept()’:
connection.cpp:323:82: error: no matching function for call to ‘boost::posix_time::seconds::seconds(Connection::<unnamed enum>)’
  323 |   m_readTimer.expires_from_now(boost::posix_time::seconds(Connection::readTimeout));
...
(it throws around 100 lines of errors)
In connection.cpp and connection.h - some searches may return 0 results, it's fine.
Replace every:
Code:
Connection::readTimeout
with:
Code:
CONNECTION_READ_TIMEOUT
Replace every:
Code:
Connection::writeTimeout
with:
Code:
CONNECTION_WRITE_TIMEOUT
Replace every:
Code:
Connection::read_timeout
with:
Code:
CONNECTION_READ_TIMEOUT
Replace every:
Code:
Connection::write_timeout
with:
Code:
CONNECTION_WRITE_TIMEOUT
in connection.h remove:
Code:
enum {writeTimeout = 30};
enum {readTimeout = 30};
in connection.h above:
Code:
class Protocol;
add:
Code:
static constexpr int32_t CONNECTION_WRITE_TIMEOUT = 30;
static constexpr int32_t CONNECTION_READ_TIMEOUT = 30;

4) Error:
Code:
game.cpp: In member function ‘Item* Game::findItemOfType(Cylinder*, uint16_t, bool, int32_t)’:
game.cpp:1725:10: error: cannot convert ‘bool’ to ‘Item*’ in return
1725 |   return false;
replace at 1725 line - it's in function "Item* Game::findItemOfType(Cylinder*, uint16_t, bool, int32_t)" - of game.cpp:
Code:
return false;
with:
Code:
return NULL;

5) Error:
Code:
luascript.cpp: In member function ‘bool LuaInterface::loadDirectory(const string&, Npc*)’:
luascript.cpp:741:23: error: ‘class boost::filesystem::directory_entry’ has no member named ‘leaf’
  741 |   std::string s = it->leaf();
In luascript.cpp replace every:
Code:
->leaf()
with:
Code:
->path().filename().string()

6) Error:
Code:
protocolgame.cpp: In member function ‘virtual void ProtocolGame::parsePacket(NetworkMessage&)’:
protocolgame.cpp:826:54: error: no match for ‘operator<<’ (operand types are ‘std::basic_ostream<char>’ and ‘std::stringstream’ {aka ‘std::__cxx11::basic_stringstream<char>’})
  826 |     s << player->getName() << " sent unknown byte: " << hex << std::endl;
or:
Code:
protocolgame.cpp:955:28: error: cannot bind ‘std::basic_ostream<char>’ lvalue to ‘std::basic_ostream<char>&&’
s << player->getName() << " sent unknown byte: " << hex << std::endl;
In protocolgame.cpp replace:
Code:
s << player->getName() << " sent unknown byte: " << hex << std::endl;
with:
Code:
s << player->getName() << " sent unknown byte: " << hex.str() << std::endl;

7) Error:
Code:
scriptmanager.cpp: In member function ‘bool ScriptManager::loadMods()’:
scriptmanager.cpp:130:23: error: ‘class boost::filesystem::directory_entry’ has no member named ‘leaf’
  130 |   std::string s = it->leaf();
In scriptmanager.cpp replace every:
Code:
->leaf()
with:
Code:
->path().filename().string()

8) Error:
Code:
talkaction.cpp: In member function ‘bool TalkActions::onPlayerSay(Creature*, uint16_t, const string&, bool)’:
talkaction.cpp:137:37: error: array must be initialized with a brace-enclosed initializer
  137 |  std::string cmd[TALKFILTER_LAST] = words, param[TALKFILTER_LAST] = "";
      |                                     ^~~~~
talkaction.cpp:137:69: error: array must be initialized with a brace-enclosed initializer
  137 |  std::string cmd[TALKFILTER_LAST] = words, param[TALKFILTER_LAST] = "";
In talkaction.cpp replace:
Code:
std::string cmd[TALKFILTER_LAST] = words, param[TALKFILTER_LAST] = "";
with:
Code:
std::string cmd[TALKFILTER_LAST] = {words, words, words}, param[TALKFILTER_LAST] = {"", "", ""};

9) Error at end of compilation:
Code:
/usr/bin/ld: connection.o: undefined reference to symbol 'pthread_condattr_setclock@@GLIBC_2.3.3'
/usr/bin/ld: /lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
In configure.ac replace:
Code:
LIBS="$LIBS $XML_LIBS"
with:
Code:
LIBS="$LIBS $XML_LIBS -lpthread"

10) Random C++ errors - warnings handled as errors, because of configuration.
Before you start searching on forum, why it does not compile, edit file makefile.am:
Search and remove:
Code:
-Wall
Code:
-Werror
Code:
-Wextra

11) Error at end of compilation:
Code:
configmanager.cpp:(.text+0x181): undefined reference to `lua_getglobal'
/usr/bin/ld: CMakeFiles/tfs.dir/src/configmanager.cpp.o: in function `(anonymous namespace)::getGlobalBoolean(lua_State*, char const*, bool)':
configmanager.cpp:(.text+0x1fc): undefined reference to `lua_getglobal'
(...)
/usr/bin/ld: CMakeFiles/tfs.dir/src/databasemanager.cpp.o: in function `DatabaseManager::updateDatabase()':
databasemanager.cpp:(.text+0x98c): undefined reference to `lua_setglobal'
Install LuaJIT:
Code:
apt install libluajit-5.1-dev
Replace cmake/FindLuaJIT.cmake file with newest TFS one:
https://github.com/otland/forgottenserver/blob/master/cmake/FindLuaJIT.cmake

12) Error:
Code:
databasemysql.cpp: In constructor ‘DatabaseMySQL::DatabaseMySQL()’:
databasemysql.cpp:47:2: error: ‘my_bool’ was not declared in this scope; did you mean ‘bool’?
   47 |  my_bool reconnect = true;
Replace in databasemysql.cpp:
Code:
my_bool reconnect = true;
With:
Code:
bool reconnect = true;

13) Error:
Code:
otserv.cpp: In function ‘void otserv(StringVec, ServiceManager*)’:
otserv.cpp:599:18: error: invalid use of incomplete type ‘RSA’ {aka ‘struct rsa_st’}
  BN_dec2bn(&g_RSA->p, g_config.getString(ConfigManager::RSA_PRIME1).c_str());
                  ^~
In file included from /usr/include/openssl/crypto.h:25,
                 from /usr/include/openssl/bio.h:20,
                 from /usr/include/openssl/asn1.h:16,
                 from /usr/include/openssl/rsa.h:16,
                 from otserv.cpp:44:
/usr/include/openssl/ossl_typ.h:110:16: note: forward declaration of ‘RSA’ {aka ‘struct rsa_st’}
typedef struct rsa_st RSA;
You must replace outdated OpenSSL library with Crypto++ and GMP libraries.
Example of replacing libraries and algorithms RSA, MD5, SHA1, SHA256, SHA512 with RSA and SHA1 (other algorithms removed) in OTX2 engine:

14) Error:
Code:
talkaction.cpp:248:15: note:   ‘std::__cxx11::basic_stringstream<char>’ is not derived from ‘std::_Setfill<_CharT>’
  248 |         ss << sl << "...";
 
talkaction.cpp:248:15: note:   cannot convert ‘sl’ (type ‘std::stringstream’ {aka ‘std::__cxx11::basic_stringstream<char>’}) to type ‘std::_Setprecision’
  248 |         ss << sl << "...";

talkaction.cpp:247:15: error: cannot bind ‘std::basic_ostream<char>’ lvalue to ‘std::basic_ostream<char>&&’
         ss << sl << "...";
Replace in talkaction.cpp:
Code:
ss << sl << "...";
With:
Code:
ss << sl.str() << "...";

15) Error:
Code:
‘lexical_cast’ is not a member of ‘boost’

creatureevent.cpp: In member function ‘bool CreatureEvents::playerLogout(Player*, bool)’:
creatureevent.cpp:146:38: error: ‘lexical_cast’ is not a member of ‘boost’
   player->setStorage(expPots, boost::lexical_cast<std::string>(expPotCharges));
                                      ^~~~~~~~~~~~
creatureevent.cpp:146:38: note: suggested alternative: ‘numeric_cast’
   player->setStorage(expPots, boost::lexical_cast<std::string>(expPotCharges));
                                      ^~~~~~~~~~~~
                                      numeric_cast
creatureevent.cpp:146:62: error: expected primary-expression before ‘>’ token
   player->setStorage(expPots, boost::lexical_cast<std::string>(expPotCharges));
At top of file - in this case creatureevent.cpp , but it can be reported in other files too - add:
Code:
#include <boost/lexical_cast.hpp>

16) Error:
Code:
talkaction.cpp: In member function ‘bool TalkActions::onPlayerSay(Creature*, uint16_t, const string&, bool)’:
talkaction.cpp:137:37: error: array must be initialized with a brace-enclosed initializer
  137 |  std::string cmdstring[TALKFILTER_LAST] = words, param[TALKFILTER_LAST] = "";
      |                                     ^~~~~
talkaction.cpp:137:69: error: array must be initialized with a brace-enclosed initializer
  137 |  std::string cmdstring[TALKFILTER_LAST] = words, paramstring[TALKFILTER_LAST] = "";
Replace in talkaction.cpp:
Code:
std::string cmdstring[TALKFILTER_LAST] = words, paramstring[TALKFILTER_LAST] = "";
With:
Code:
std::string cmdstring[TALKFILTER_LAST] = {words, words, words}, paramstring[TALKFILTER_LAST] = {"", "", ""};

To apply all changes, you MUST run all 3 commands again:
Code:
sh autogen.sh
./configure --enable-mysql --disable-dependency-tracking
sh build.sh

If you get any compilation error not listed above, post it in this thread.
(only problems with compiling old OTS engines on Debian 9 / 10 and Ubuntu 20.04)

You can also send errors to me by Discord: Gesior.pl#3208
for using visual studio with microsoft vcpkg.
I know it's for Ubuntu but I'm using it for both sides.

In connection.cpp
Add
below #include "server.h":

Code:
#if BOOST_VERSION >= 107000
#define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context())
#else
#define GET_IO_SERVICE(s) ((s).get_io_service())
#endif

And after replace:
C++:
socket.get_io_service().dispatch(std::bind(&Connection::broadcastMessage, shared_from_this(), msgCopy));

with:
C++:
GET_IO_SERVICE(socket).dispatch(std::bind(&Connection::broadcastMessage, shared_from_this(), msgCopy));
 
otsystem.h: In function ‘int64_t OTSYS_TIME()’:
otsystem.h:115:14: warning: ‘int ftime(timeb*)’ is deprecated: Use gettimeofday or clock_gettime instead [-Wdeprecated-declarations]
115 | ftime(&t);
| ~~^~~~
In file included from otsystem.h:76,
from player.h:20,
from party.h:20,
from party.cpp:18:
/usr/include/x86_64-linux-gnu/sys/timeb.h:29:12: note: declared here
29 | extern int ftime (struct timeb *__timebuf)
| ^~
make[1]: Leaving directory '/home/diego/trunk.r3777'
make: *** [Makefile:456: all] Error 2
root@ubuntu:/home/diego/trunk.r3777# otsystem.h:115:14: warning: ‘int ftime(timeb*)’ is deprecated: Use gettimeofday or clock_gettime instead [-Wdeprecated-declarations]
115 | ftime(&t);
bash: syntax error near unexpected token `('
bash: syntax error near unexpected token `&'
 
Hey guys,

Did as in tutorial - changed lines with /tr1/ and std but still getting same error :(
configure: error: "boost::unordered_set header not found."
Can any1 help please?
 
@Gesior.pl

Bash:
checking for main in -lboost_filesystem-mt... no
checking for main in -lboost_filesystem... yes
checking boost/asio.hpp usability... no
checking boost/asio.hpp presence... yes
configure: WARNING: boost/asio.hpp: present but cannot be compiled
configure: WARNING: boost/asio.hpp:     check for missing prerequisite headers?
configure: WARNING: boost/asio.hpp: see the Autoconf documentation
configure: WARNING: boost/asio.hpp:     section "Present But Cannot Be Compiled"
configure: WARNING: boost/asio.hpp: proceeding with the compiler's result
checking for boost/asio.hpp... no
configure: error: "boost::asio header not found."


Could you advise on this? Im trying to compile tfs 0.3.6 on ubuntu 18
 
Back
Top