From 783578d28ec6f7d61e7a4b55c608f4f54b725df7 Mon Sep 17 00:00:00 2001 From: fusion32 Date: Fri, 15 Aug 2025 14:59:56 -0300 Subject: [PATCH] wrapping up for a public release --- LICENSE.txt | 24 ++++++++++++++++++++++++ Makefile | 4 ++-- README.md | 13 +++++++++++++ config.cfg | 2 +- src/common.cc | 2 ++ src/connections.cc | 4 ++-- src/login.hh | 2 +- src/query.cc | 6 +++--- tibia-login.service | 22 ++++++++++++++++++++++ 9 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 tibia-login.service diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..c32dd18 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to \ No newline at end of file diff --git a/Makefile b/Makefile index c456577..d0c16d3 100644 --- a/Makefile +++ b/Makefile @@ -3,12 +3,12 @@ BUILDDIR = build OUTPUTEXE = login CXX = g++ -CXXFLAGS = -m64 -fno-strict-aliasing -pedantic -Wno-unused-parameter -Wall -Wextra -pthread --std=c++11 +CXXFLAGS = -m64 -fno-strict-aliasing -pedantic -Wno-deprecated-declarations -Wno-unused-parameter -Wall -Wextra -pthread --std=c++11 LFLAGS = -Wl,-t -lcrypto DEBUG ?= 0 ifneq ($(DEBUG), 0) - CXXFLAGS += -g -O0 + CXXFLAGS += -g -Og else CXXFLAGS += -O2 endif diff --git a/README.md b/README.md new file mode 100644 index 0000000..fdd9524 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# Tibia 7.7 Login Server +This is a simple login server designed to support [Tibia Game Server](https://github.com/fusion32/tibia-game). + +## Compiling +Even though there are no Linux specific features being used, it will currently only compile on Linux. It should be simple enough to support compiling on Windows but I don't think it would add any value, considering the querymanager will be running on Linux and that they need to be both on the same machine. The makefile is very simple and should work as long as OpenSSL's libcrypto, which is the only dependency, is installed. You can add the `-j N` switch to make it compile across N processes. +``` +make # build in release mode +make DEBUG=1 # build in debug mode +make clean # remove `build` directory +``` + +## Running +Similar to the game server, the login server won't boot up if it's not able to connect to the [Query Manager](https://github.com/fusion32/tibia-querymanager). That said, running it is straighforward, requiring only the RSA private key `tibia.pem` and `config.cfg` files to be in the working directory. It is always recommended that the server is setup as a service. There is a *systemd* configuration file (`tibia-login.service`) in the repository that may be used for that purpose. The process is very similar to the one described in the [Game Server](https://github.com/fusion32/tibia-game) so I won't repeat myself here. diff --git a/config.cfg b/config.cfg index 458a0c0..913e60c 100644 --- a/config.cfg +++ b/config.cfg @@ -4,5 +4,5 @@ LoginPort = 7171 MaxConnections = 10 LoginTimeout = 10s QueryManagerHost = "127.0.0.1" -QueryManagerPort = 7174 +QueryManagerPort = 7173 QueryManagerPassword = "a6glaf0c" diff --git a/src/common.cc b/src/common.cc index 2a40df2..c4786e2 100644 --- a/src/common.cc +++ b/src/common.cc @@ -13,6 +13,7 @@ void LogAdd(const char *Prefix, const char *Format, ...){ LocalTime.tm_year + 1900, LocalTime.tm_mon + 1, LocalTime.tm_mday, LocalTime.tm_hour, LocalTime.tm_min, LocalTime.tm_sec, Prefix, Entry); + fflush(stdout); } } @@ -32,6 +33,7 @@ void LogAddVerbose(const char *Prefix, const char *Function, LocalTime.tm_year + 1900, LocalTime.tm_mon + 1, LocalTime.tm_mday, LocalTime.tm_hour, LocalTime.tm_min, LocalTime.tm_sec, Prefix, Function, Entry); + fflush(stdout); } } diff --git a/src/connections.cc b/src/connections.cc index 5fd885f..ac5d4ca 100644 --- a/src/connections.cc +++ b/src/connections.cc @@ -265,8 +265,8 @@ void ProcessConnections(void){ } if(AssignConnection(Socket, Addr, Port) == NULL){ - LOG_ERR("Rejecting connection from %08X due to max number of" - " connections being reached (%d)", Addr, g_MaxConnections); + LOG_ERR("Rejecting connection from %08X:%d due to max number of" + " connections being reached (%d)", Addr, Port, g_MaxConnections); close(Socket); } } diff --git a/src/login.hh b/src/login.hh index 99c8ceb..aa391a1 100644 --- a/src/login.hh +++ b/src/login.hh @@ -290,7 +290,7 @@ struct TWriteBuffer{ } void Rewrite16(int Position, uint16 Value){ - if((Position + 2) <= this->Position){ + if((Position + 2) <= this->Position && !this->Overflowed()){ BufferWrite16LE(this->Buffer + Position, Value); } } diff --git a/src/query.cc b/src/query.cc index 1335631..21d44ec 100644 --- a/src/query.cc +++ b/src/query.cc @@ -147,7 +147,7 @@ int ExecuteQuery(TQueryManagerConnection *Connection, bool AutoReconnect, } const int MaxAttempts = 2; - for(int Attempts = 0; true; Attempts += 1){ + for(int Attempt = 1; true; Attempt += 1){ int WriteSize = WriteBuffer->Position; if(!IsConnected(Connection)){ if(!AutoReconnect){ @@ -173,7 +173,7 @@ int ExecuteQuery(TQueryManagerConnection *Connection, bool AutoReconnect, if(!WriteExact(Connection->Socket, Connection->Buffer, WriteSize)){ Disconnect(Connection); - if(Attempts >= MaxAttempts){ + if(Attempt >= MaxAttempts){ LOG_ERR("Failed to write request"); return QUERY_STATUS_FAILED; } @@ -183,7 +183,7 @@ int ExecuteQuery(TQueryManagerConnection *Connection, bool AutoReconnect, uint8 Help[4]; if(!ReadExact(Connection->Socket, Help, 2)){ Disconnect(Connection); - if(Attempts >= MaxAttempts){ + if(Attempt >= MaxAttempts){ LOG_ERR("Failed to read response size"); return QUERY_STATUS_FAILED; } diff --git a/tibia-login.service b/tibia-login.service new file mode 100644 index 0000000..567806d --- /dev/null +++ b/tibia-login.service @@ -0,0 +1,22 @@ +# Basic SYSTEMD service file for the Tibia Login Server + +[Unit] +Description=Tibia Login Server +After=network.target +Requires=tibia-querymanager.service + +[Install] +WantedBy=multi-user.target + +[Service] +Type=simple +User=tibia-login +Group=tibia-login +ExecStart=/opt/tibia/login/login +WorkingDirectory=/opt/tibia/login/ +Restart=always +RestartSec=10 +LimitCORE=infinity +StandardOutput=journal +StandardError=journal +SyslogIdentifier=%n